数据库管理员

希望提高数据库技能并向社区中的其他人学习的数据库专业人员的问答

1
在仅接收INSERT的表上运行VACUUM是否值得?
在2015年的re:Invent谈话中,AWS提到,不仅应在更新或删除之后运行真空,而且还应在插入之后运行真空。这是演讲的相关部分: http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s 假设即使块仅接收插入,也必须对其进行一些清理,并且可以在第一次选择块时(降低读取速度)或在真空期间进行清理。这是真的吗?如果是,那么到底必须执行什么清理工作?

3
强制流量不同
我有一张这样的桌子: CREATE TABLE Updates ( UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY, ObjectId INT NOT NULL ) 本质上跟踪ID不断增加的对象的更新。 该表的使用者将选择一个由100个不同的对象ID组成的块,这些ID UpdateId由一个特定的并从其开始UpdateId。从本质上讲,跟踪它停止的位置,然后查询任何更新。 我发现这是一个有趣的优化问题,因为我只能通过编写恰好由于索引而做我想要做的查询的查询来生成一个最大最优查询计划,但不能保证我想要的: SELECT DISTINCT TOP 100 ObjectId FROM Updates WHERE UpdateId > @fromUpdateId @fromUpdateId存储过程参数在哪里。 有以下计划: SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek 由于UpdateId正在使用对索引的查找,因此结果已经不错,并且可以按照我想要的那样从最低更新ID到最高更新ID进行排序。这会生成一个流程明确的计划,这正是我想要的。但是排序显然不能保证行为,所以我不想使用它。 此技巧还导致了相同的查询计划(尽管具有冗余的TOP): …

3
负载下插入性能提高:为什么?
我有一段代码可以对高度非规范化的表执行插入操作。这些表的列数范围从〜100到300+。这是在Windows Server 2008上运行的SQL Server 2008 R2。 每个插入包括在同一事务下插入多个表。有些插入是由NHibernate批处理的,但是有些不能,但是它们都在同一事务下。 当我通过重复调用一段执行插入的代码执行了500次插入操作时,平均得到的时间约为360毫秒。 奇怪的是,当我使用4个进程同时运行测试代码(在Windows Server 2008下从4个不同的命令提示符运行同一个exe)时,每次调用的插入性能会好得多。我看到突发速度高达90毫秒(几乎快了X4)。我正在从代码中测量插入时间。 由于4个进程彼此之间一无所知,因此我假设这与SQL Server有关,但是我绝对不知道为什么。我想知道为什么会这样,以及是否有任何配置可以使我在插入频率不那么高的情况下获得相同的性能。 同样欢迎提出有关SQL Server监视方法的建议,以了解数据库级别的情况。

2
面试SQL问题
给表“员工” employee_id | salary | department_id -------------+--------+--------------- 只有使用SQL才能找到从一个部门转移到另一个部门的所有员工转移方式,因此“离职”部门和“到达”部门的平均薪水都在增长。 PS:我在一次采访中被问到这个问题,但从未给出答案,而Google几乎没有帮助。

2
为什么TVP必须是READONLY,为什么其他类型的参数不能是READONLY
根据此博客,如果函数或存储过程的OUTPUT参数不是参数,则它们本质上是按值传递的;如果它们是参数,则本质上应视为传递引用的更安全的版本OUTPUT。 最初,我认为强制声明TVP的目的READONLY是向开发人员明确表示不能将TVP用作OUTPUT参数,但由于我们无法将非TVP声明为,因此还必须继续进行下去READONLY。例如,以下失败: create procedure [dbo].[test] @a int readonly as select @a 消息346,级别15,状态1,过程测试 参数“ @a”不是表值参数,因此不能声明为READONLY。 由于统计数据未存储在TVP上,因此阻止DML操作的原理是什么? 是否与OUTPUT出于某些原因不希望TVP成为参数有关?


2
LOB_DATA,慢速表扫描和一些I / O问题
我有一个相当大的表,其中一列是XML数据,XML条目的平均大小约为15 KB。所有其他列都是常规int,bigints,GUID等。要获得一些具体数字,我们假设该表有100万行,大小约为15 GB。 我注意到的是,如果我要选择所有列,则从此表选择数据的速度确实很慢。当我做 SELECT TOP 1000 * FROM TABLE 从磁盘读取数据大约需要20-25秒-即使我没有对结果施加任何顺序。我使用冷缓存(即之后DBCC DROPCLEANBUFFERS)运行查询。以下是IO统计信息: 扫描计数1,逻辑读取364,物理读取24,预读7191,lob逻辑读7924,lob物理读1690,lob预读3968。 它捕获约15 MB的数据。执行计划按预期显示了聚集索引扫描。 除了查询外,磁盘上没有任何IO。我还检查了聚簇索引碎片是否接近0%。这是消费级的SATA驱动器,但是我仍然认为SQL Server能够以超过100-150 MB / min的速度扫描表。 XML字段的存在会导致大多数表数据位于LOB_DATA页上(实际上,约90%的表页都是LOB_DATA)。 我想我的问题是-我是否正确地认为LOB_DATA页会导致缓慢的扫描,不仅是因为它们的大小,还因为当表中有很多LOB_DATA页时,SQL Server无法有效地扫描聚集索引吗? 更广泛地讲-具有这样的表结构/数据模式是否合理?使用Filestream的建议通常会指出更大的字段大小,所以我真的不想走那条路。我还没有真正找到有关此特定情况的任何好信息。 我一直在考虑XML压缩,但是它需要在客户端或SQLCLR上完成,并且需要在系统中进行大量工作。 我尝试了压缩,并且由于XML是高度冗余的,因此我可以(在ac#应用程序中)将XML从20KB压缩到〜2.5KB并将其存储在VARBINARY列中,从而避免使用LOB数据页。在我的测试中,SELECT的速度提高了20倍。

4
实体关系问题
我有4个与此相关的表(这是一个示例): Company: ID Name CNPJ Department: ID Name Code ID_Company Classification: ID Name Code ID_Company Workers: Id Name Code ID_Classification ID_Department 假设我有一个classification带id = 20, id_company = 1。并且department具有id_company = 2(代表另一家公司)。 这将允许创建来自两家公司的工人,因为分类和部门分别链接到该公司。我不希望这种情况发生,所以我认为我的人际关系存在问题,我不知道该如何解决。


2
口音敏感排序
为什么这两个SELECT语句导致排序顺序不同? USE tempdb; CREATE TABLE dbo.OddSort ( id INT IDENTITY(1,1) PRIMARY KEY , col1 NVARCHAR(2) , col2 NVARCHAR(2) ); GO INSERT dbo.OddSort (col1, col2) VALUES (N'e', N'eA') , (N'é', N'éB') , (N'ë', N'ëC') , (N'è', N'èD') , (N'ê', N'êE') , (N'ē', N'ēF'); GO SELECT * FROM dbo.OddSort ORDER BY col1 …

2
PostgreSQL最大化性能SSD
我将拥有一个庞大的PostgreSQL 9.3数据库,其中包含许多表,每个表的条目超过100M。该数据库基本上将是只读的(一旦我填写了所有必要的表,并且不再在DB上进行写操作,就不再建立索引)和单用户访问(从本地主机运行并基准化多个查询),因为将使用DB仅用于研究目的。查询将始终在整数DB字段上使用JOIN。 我可能会为此目的购买SSD(256-512GB)。我以前没有为数据库使用SSD,所以我应该担心什么?我可以将整个数据库放到SSD上还是将索引放到硬盘上?调整PostgreSQL的SSD是否需要任何特别的建议/教程?请注意,我有一个不错的工作站,配备了i7和32Gb RAM,因此也许您也可以在那里提供一些建议。

4
标识列上的索引是否应该非聚集?
对于具有标识列的表,是否应为标识列创建聚集或非聚集的PK /唯一索引? 原因是将为查询创建其他索引。使用非聚集索引(在堆上)并返回该索引未覆盖的列的查询将使用较少的逻辑I / O(LIO),因为没有额外的聚集索引b树查找步骤? create table T ( Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table) A .... -- A, B, C have mixed data type of int, date, varchar, float, money, .... B .... C .... ....) create …

3
跟踪标志4199-全局启用?
这可能属于观点类别,但我很好奇是否人们使用跟踪标志4199作为SQL Server的启动参数。对于那些使用过它的人,您在什么情况下遇到查询回归? 当然,这似乎似乎是潜在的整体性能优势,我正在考虑在我们的非生产环境中在全球范围内启用它,并将其放置几个月以找出任何问题。 2014年(或2016年)默认情况下是否将4199中的修补程序纳入优化程序?尽管我理解不引入计划外更改的情况,但将所有这些修复隐藏在版本之间似乎很奇怪。 我们使用的是2008、2008R2,大部分使用的是2012。

2
锁定创建表
在另一个应用程序中,我被糟糕的设计所震惊:多个线程EnsureDatabaseSchemaExists()同时执行一个方法,基本上看起来像这样: IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'MyTable') AND type = N'U') BEGIN CREATE TABLE MyTable ( ... ); END 但是,即使在SERIALIZABLE事务中执行,此代码似乎也不是线程安全的(即,并行代码尝试多次创建表)。有没有机会强迫SELECT语句获取一个锁定,从而防止另一个线程执行相同的SELECT语句? 多线程EnsureSchemaExists()方法是否有更好的模式?

3
如何最好地衡量查询性能?
我有2个存储过程,其中第二个存储过程是第一个存储过程的改进。 我正在尝试确切地衡量这是多少改进。 1 /测量clock time似乎不是一种选择,因为我得到不同的执行时间。更糟糕的是,有时(很少,但确实会发生)第二个存储过程的执行时间大于第一个存储过程的执行时间(我想是由于当时服务器的工作量)。 2 / Include client statistics也提供不同的结果。 3 / DBCC DROPCLEANBUFFERS,DBCC FREEPROCCACHE是不错的,但同样的故事... 4 / SET STATISTICS IO ON可能是一种选择,但是由于我的存储过程中涉及许多表,我如何获得总体得分? 5 / Include actual execution plan也可以选择。estimated subtreecost对于第一个存储过程,我得到0.3253,对于第二个存储过程,我得到0.3079。我可以说第二个存储过程快了6%(= 0.3253 / 0.3079)吗? 6 /是否使用SQL Server Profiler中的“读取”字段? 那么,无论执行条件如何(服务器的工作负载,执行这些存储过程的服务器等),我怎么能说第二个存储过程比第一个过程快x%? 如果不可能,如何证明第二个存储过程比第一个存储过程有更好的执行时间?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.