在对慢查询进行调查期间,执行计划似乎异常次优(嵌套循环执行了 900 万次执行搜索,其中估计执行次数为 1)。在确认了一些确实过时的相关统计数据后,我重建了统计数据并且性能问题得到了有效解决。
此数据库启用了自动更新统计信息(默认情况下启用)。我知道有一个基于 20% + 500 行修改(更新/插入/删除)的自动统计更新阈值。多个索引似乎已在很大程度上超过了此阈值,因此似乎存在 (A) 自动更新问题或 (B) 更新策略比我在网上找到的更多文档。
我很欣赏可以设置计划任务来更新统计信息,如果找不到其他解决方案,这可能是我们采取的方法,但它确实让我们感到困惑,为什么如此大量的修改不会触发某些统计数据的自动更新 - 了解为什么可能会帮助我们决定哪些统计数据需要由计划任务更新。
一些补充说明:
在负载测试创建数据的数据库中注意到了该问题,因此在短时间内添加了大量数据,因此如果自动更新定期发生(例如,最多一天一次)那么这可以解释一些观察到的行为。此外,我们的负载测试往往会给数据库带来很大的压力,因此我想知道 SQL 是否在负载很重时推迟了统计信息更新(随后由于某种原因不更新统计信息)。
在尝试使用包含连续 INSERT、SELECT 和 DELETE 语句的测试脚本重新创建此问题时,问题并未发生。我想知道这里的区别是否是这些语句每个都会影响每个 SQL 语句的许多行,而我们的负载测试脚本倾向于单独插入行。
有问题的数据库设置为“简单”恢复模式。
一些相关链接:
我也通过微软连接提出了这个问题:
更新 2011-06-30:
在进一步调查中,我相信超出阈值级别(例如 500 行 + 20%)的统计数据是问题查询未使用的统计数据,因此它们可能会在查询运行时更新这需要他们。对于该统计数据是通过查询中使用,这些被定期更新。剩下的问题是,仅在相对较少的插入之后,这些统计数据就会严重误导查询计划优化器(例如,在估计数量为 1 的情况下导致上述 900 万次左右的搜索)。
我此时的预感是问题与主键选择不当有关,键是使用 NEWID() 创建的唯一标识符,因此这会很快创建高度碎片化的索引 - 特别是作为 SQL 中的默认填充因子服务器是 100%。我的预感是,在相对较少的行插入后,这会以某种方式导致误导性统计数据 - 低于重新计算统计数据的阈值。这可能都不是问题,因为我已经生成了大量数据而没有中途重建索引,因此糟糕的统计数据可能是由此产生的非常高的索引碎片的结果。我想我需要将 SQL Server 维护周期添加到我的负载测试中,以便更好地了解真实系统长时间内的性能。
更新 2012-01-10:
另一个需要考虑的因素。SQL Server 2005 中添加了两个跟踪标志(并且似乎在 2008 年仍然存在)以解决与出现过时和/或误导性统计数据相关的特定缺陷。有问题的标志是:
DBCC TRACEON(2389)
DBCC TRACEON(2390)
Run Code Online (Sandbox Code Playgroud)
MSDN:Ian Jose 的 WebLog:升序键和自动快速更正统计 数据,Fabiano Amorim
在决定启用这些标志时,您当然应该非常小心,因为它们可能会产生不利影响。
我想知道在未提交读隔离级别下脏读“有多脏” 。我知道已更新但尚未提交的行是可见的,但是:
更新:经过一些辩论,最小的共识是,如果列大小大于 8KB,脏读,即使在列本身内,也是可能的。
我们的一位客户刚刚升级到新服务器。
对于一个特定的存储过程,第一次执行它需要三分钟的时间来运行。后续运行不到 1 秒。
这让我相信最初的三分钟主要用于计算执行计划。后续运行只需使用缓存的计划并立即运行。
在我们的测试数据库上,计算相同程序的计划大约需要 5 秒。
我在计划本身中没有看到任何可怕的东西 - 尽管我不认为它是相关的,因为计划显示了运行查询需要多长时间,而不是计算本身。
该服务器为 16 核,24 GB 内存。不会发生沉重的 CPU 或内存负载。
是什么导致仅在特定数据库上计算如此缓慢?
我可以采取哪些步骤来找出问题的原因?
编辑
所以我设法访问服务器并使用SET SHOWPLAN_XML ON运行查询。
我可以确认查询的 CompileTime 占用了查询执行时间的 99%。该StatementOptmEarlyAbortReason是“超时”,我们与他们的数据库副本的原因是MemoryLimitExceeded测试数据库。
我有一个包含数百万行的表,我需要不时从中运行一些查询。第一个查询通常会很慢(大约 10 秒),随后的查询通常会更快(大约 1 秒)。几个小时后,一个缓慢/然后快速的循环再次开始。
我已经在我的执行计划中检查了所有需要的索引都存在并得到了适当的使用,我认为性能差异是由于索引实际上在内存中用于后续查询(我是对的,还是有其他可能的原因?)
我还使用索引运行了许多其他查询,但这些查询耗时较少,性能也不那么重要,所以我担心这些索引实际上是将我的关键索引从内存缓存中推出。
除了明显的“添加更多 RAM”修复之外,我一直在考虑编写虚拟查询脚本,使其每小时运行一次,以强制索引返回内存。
有没有更优雅的方法来做到这一点?就像暗示 SQLServer 的一种方式,如果它只有足够的内存来保持一个索引缓存,它应该是那个?
我知道通常最好的办法是不要在这类事情上搞砸 SQLServer,但是我的查询的不寻常性质(很少运行,但对时间要求严格)让我相信它是有意义的(如果可能的话) .
我也很想知道是否有办法知道在给定时间哪些索引缓存在内存中?
最近,我们的索引出现了许多问题,我们的 DBA 团队将这些问题归因于最近没有运行的统计数据。这让我想知道 - 我如何检查最近是否通过 SQL Management Studio 更新了统计信息?
如果这个问题没有很好地解释这一点,我深表歉意 - 直到现在我才开始接触统计数据,在此之前,每当我遇到与性能相关的问题时都会查看索引。
编辑:
我正在使用以下内容但收到语法错误:
use *databasename*
exec sp_autostats *schema.tablename*
Run Code Online (Sandbox Code Playgroud)
我收到的错误是:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '.'.
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
我正在玩 HierarchyId,但我还没有想出一种基于集合的方法来执行以下操作:
这个问题与我之前的问题有关,我怀疑使用 HierarchyId 完成这两个任务的唯一方法是一次一个节点或一个级别。如果我使用的是物化路径,那么这两个操作都可以通过一个(且简单的)基于集合的命令轻松完成。
我错过了什么?
编辑:我也错过了移动子树的方法,但我是从 Mikael Eriksson 的评论中学到的
在我的 SQL Server 数据库中,我有一datetime列。
创建代表列long值的新列的好方法是什么datetime?在long将表示了若干秒。
我想如果我可以将它转换为longs,那么在一段时间内按查询分组会更容易,因为我可以将长数除以固定数量。
该表是静态的,不会更新或删除数据。
是否可以在 SQL Server 2008 中设置警报,以便在特定类别中的作业失败时发送电子邮件?
我想知道,因为我想在 SSRS 订阅失败时设置电子邮件 - 所有这些订阅都是Report Server类别中的作业。
编辑- 事实证明,当 SSRS 订阅失败时,作业本身不会失败,因此我的问题不适用于 SSRS 订阅监视使用。但是我仍然想知道我们在我们的环境中运行的其他作业
我有一个应用程序,它每年向表中插入超过 10 亿行。此表包含一些varchar和bigint列和一个 blob 列。
这 10 亿行包含用于跟踪目的的历史数据。所以我想知道如果我根据这篇关于最大表大小的 MSDN 文章继续采用这种结构,是否会有表容量限制。
该链接中提到的数据文件大小是否指的是表数据文件组?
继续我最近玩大数字的趋势,我最近将一个错误归结为以下代码:
DECLARE @big_number DECIMAL(38,0) = '1' + REPLICATE(0, 37);
PRINT @big_number + 1;
PRINT @big_number - 1;
PRINT @big_number * 1;
PRINT @big_number / 1;
Run Code Online (Sandbox Code Playgroud)
我为此代码得到的输出是:
10000000000000000000000000000000000001
9999999999999999999999999999999999999
10000000000000000000000000000000000000
Msg 8115, Level 16, State 2, Line 6
Arithmetic overflow error converting expression to data type numeric.
Run Code Online (Sandbox Code Playgroud)
什么?
为什么前 3 个操作有效,而最后一个无效?如果@big_number显然可以存储 的输出,怎么会出现算术溢出错误@big_number / 1?
sql-server-2008 ×10
sql-server ×9
performance ×2
t-sql ×2
buffer-pool ×1
datatypes ×1
datetime ×1
hierarchy ×1
index ×1
monitoring ×1
ssrs ×1