标签: statistics

使用 STATISTICS_NORECOMPUTE 的可取性

我最近参与维护一组具有一些有趣索引问题的数据库。最让我恼火的是开发、测试、模型和生产机器之间的指标差异。由于差异使得调优查询变得相当困难,因此同步它们是我的第一个项目之一。

当我比较了测试和模型环境时,我注意到模型环境中的大多数索引都STATISTICS_NORECOMPUTE设置为 ,ON而测试中的索引没有。在所有环境中,都有更新所有数据库统计信息的夜间作业。

我以前从未处理过STATISTICS_NORECOMPUTE,所以这里是我的问题。处理此设置时是否有任何最佳做法?如果我在一天结束时进行统计更新,最好打开STATISTICS_NORECOMPUTE所有索引的所有环境?或者有充分的理由不这样做吗?

编辑:我发现了金佰利特里普的关于这一主题的博客之一在这里,似乎表明STATISTICS_NORECOMPUTE应谨慎充其量只能使用。但我仍然担心在全球范围内关闭它。有没有人试过这个,他们经历了什么?

index sql-server statistics sql-server-2008-r2

11
推荐指数
1
解决办法
7444
查看次数

在生产服务器中运行 sp_updatestats 有什么影响?

sp_updatestats在生产环境中的 SQL Server上运行是否安全?

或者更确切地说,更新 sql server 上的所有统计信息有什么影响?它可以在运行时“阻塞”sql server 并导致用户超时或其他问题吗?

sql-server statistics sql-server-2008-r2 index-statistics

11
推荐指数
1
解决办法
1万
查看次数

了解统计数据、执行计划和“上升的关键问题”

我试图更好地理解(从概念上)统计、执行计划、存储过程执行之间的关系。

我说统计信息仅在为存储过程创建执行计划时使用,而在实际执行上下文中不使用,我说的对吗?换句话说,如果这是真的,一旦创建了计划(并假设它被正确重用),“最新”统计数据有多重要?

我读过的一篇文章(统计、行估计和升序日期列)特别激励我,该文章描述的场景与我每天面对的几个客户数据库非常相似。

在我们使用特定存储过程定期查询的最大表之一中,我们有一个升序日期/时间列。

当您每天添加十万行时,您如何防止执行计划变得陈旧?

如果我们经常更新统计信息来解决这个问题,在这个存储过程的查询中使用 OPTION (RECOMPILE) 提示是否有意义?

任何意见或建议将不胜感激。

更新:我使用的是 SQL Server 2012 (SP1)。

sql-server statistics execution-plan sql-server-2012

11
推荐指数
2
解决办法
3249
查看次数

VACUUM FULL 是否需要 ANALYZE

如果您能深入了解VACUUMPostgreSQL 9.3 中的功能,我将不胜感激。我通读了文档并进行了一些搜索,但找不到明确的答案。

我正在为 9.3 服务器设置每周一次的数据库维护工作。

其中一部分将是一个VACUUM FULL. 这是一个很小的数据库,我有一个不错的周末维护窗口,所以我可以FULL毫无问题地运行它。

ANALYZE在命令中添加选项有什么意义吗?

根据 9.3 文档:

VACUUM FULL 将表的全部内容重写到一个没有额外空间的新磁盘文件中,允许将未使用的空间返回给操作系统。

如果表已完全重新创建,那么我是否需要特别要求ANALYZE发生或在将行写入表的新版本时自动更新统计信息?

postgresql statistics vacuum postgresql-9.3

11
推荐指数
1
解决办法
4915
查看次数

为什么我的索引查找可以估计正确的行数而排序运算符不能?

我有一个在谓词上使用函数的查询,如下所示:

commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)
Run Code Online (Sandbox Code Playgroud)

我在 commentType 上有一个过滤索引,它有 40K 行,当我运行查询时,Index Seek 的估计行数非常准确(大约 11K),但对于下一步(排序运算符),它完全忽略了统计信息和只是估计过滤索引中的总行数。

为什么会这样?我知道有关sargability的基础知识,并且我只是为了理智而进行了测试,将 dateadd 替换为实际日期(2014-01-01),瞧......排序开始正确猜测行数......

为什么会发生这种情况,我该如何解决?我不能通过一个固定的日期...

index sql-server statistics

11
推荐指数
1
解决办法
387
查看次数

为什么将 Auto Update Statistics 设置为 False?

作为更广泛的收购项目的一部分,我刚刚继承了大约 20 个 SQL Server 实例。我正在评估性能,我不喜欢维护计划的实施方式。

我每天都在看到全面的索引重建(我可以处理这个)以及每天手动更新统计数据。

大约一半的数据库已设置为 Auto Update Statistics = False,原因尚不清楚,除了我被告知是为了减少“性能问题”...

我一直认为并致力于将其设置为 True 的最佳实践,并认为如果此设置为 True,则不需要手动更新。我错了吗?

任何人都可以解释将此设置为 False 的好处是什么,而是每天进行手动更新?

我应该提到一些数据库是高度事务性的(每天数百万次插入、删除、更新),其他数据库在事务率方面很低,有些几乎是只读的。虽然没有押韵或理由将自动更新设置设置为 False。好像是彩票。

performance sql-server statistics index-statistics

11
推荐指数
3
解决办法
1万
查看次数

永无止境的查询存储搜索

我从一开始说,我的问题/问题类似于之前的一个,但因为我不知道的原因或起始信息是一样的,我决定后,我的问题有一些更多的细节。

手头问题:

  • 在一个奇怪的时间(接近工作日结束),一个生产实例开始出现异常行为:
    • 实例的高 CPU(从大约 30% 的基线增加到大约两倍并且仍在增长)
    • 增加的事务数/秒(尽管应用程序负载没有看到任何变化)
    • 增加空闲会话数
    • 从未显示此行为的会话之间的奇怪阻塞事件(即使读取未提交的会话也会导致阻塞)
    • 间隔的顶部等待是非页面闩锁排在第一位,锁排在第二位

初步调查:

  • 使用 sp_whoIsActive 我们看到我们的监控工具执行的查询决定运行速度极慢并占用大量 CPU,这是以前从未发生过的;
  • 其隔离级别未提交读取;
  • 我们查看了我们看到古怪数字的计划:StatementEstRows="3.86846e+010" 有大约 150 TB 的估计数据要返回
  • 我们怀疑是监控工具的查询监控功能造成的,所以我们禁用了该功能(我们还向我们的提供商开了一张票,以检查他们是否知道任何问题)
  • 从第一个事件开始,它又发生了几次,每次我们终止会话,一切都会恢复正常;
  • 我们意识到该查询与MS 在 BOL 中用于查询存储监控的查询之一极为相似- 最近性能下降的查询(比较不同时间点)
  • 我们手动运行相同的查询并看到相同的行为(CPU 使用不断增加,增加闩锁等待,意外锁定......等)

有罪查询:

Select qt.query_sql_text, 
    q.query_id, 
    qt.query_text_id, 
    rs1.runtime_stats_id AS runtime_stats_id_1,
    interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time), 
    p1.plan_id AS plan_1, 
    rs1.avg_duration AS avg_duration_1, 
    rs2.avg_duration AS avg_duration_2,
    p2.plan_id AS plan_2, 
    interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time), 
    rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt 
Inner Join sys.query_store_query AS …
Run Code Online (Sandbox Code Playgroud)

statistics system-tables sql-server-2016 query-store

11
推荐指数
2
解决办法
1229
查看次数

为什么SQL Server不做复合列统计直方图?

SQL Server 有一种叫做“多列统计”的东西,但这并不是人们认为的意思。

我们来看看下面的示例表:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);
Run Code Online (Sandbox Code Playgroud)

这样,我们就在我们拥有的两个索引上创建了两个统计信息:

BadIndex 的统计数据:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS …
Run Code Online (Sandbox Code Playgroud)

sql-server statistics

10
推荐指数
1
解决办法
1333
查看次数

为什么我的 Azure SQL (SQL Server) 数据库会在一段时间内因数据 IO 过载?

我在 S2 版本 (50 DTU) 下运行 Azure SQL 数据库。正常使用服务器通常会挂在10%左右的DTU。但是,此服务器会定期进入一种状态,它将在数小时内将数据库的 DTU 使用率发送到 85-90%。然后突然间它恢复到正常的 10% 使用率。

在此处输入图片说明

在这种过载状态下,应用程序对服务器的查询似乎仍在快速运行。

我可以从 S2 => 任何东西(例如 S3) => S2 扩展服务器,它似乎清除了它挂在的任何状态。但是几个小时后它会再次重复相同的过载状态循环。我注意到的另一件奇怪的事情是,如果我在 S3 计划 (100 DTU) 24/7 上运行此服务器,我没有观察到这种行为。只有当我将数据库缩小到 S2 计划 (50 DTU) 时才会出现这种情况。在 S3 计划中,我始终保持 5-10% 的 DTU 使用率。显然没有得到充分利用。

我已经检查了 Azure SQL 查询报告以查找恶意查询,但我并没有真正看到任何异常,它显示我的查询使用资源,正如我所期望的那样。

在此处输入图片说明

正如我们在这里看到的,使用量都来自数据 IO。如果我在此处更改性能报告以显示 MAX 的顶级数据 IO 查询,我们会看到:

在此处输入图片说明

查看这些长期运行的查询似乎指向统计更新。并不是真正从我的应用程序运行的任何东西。例如,查询 16302 显示:

SELECT StatMan([SC0], [SC1], [SC2], [SB0000]) FROM (SELECT TOP 100 PERCENT [SC0], [SC1], [SC2], step_direction([SC0]) over (order by NULL) AS [SB0000]  FROM (SELECT [UserId] AS [SC0], [OrganizationId] AS …
Run Code Online (Sandbox Code Playgroud)

sql-server statistics azure-sql-database

10
推荐指数
1
解决办法
5131
查看次数

键之间基数差异较大的表的基数估计

语境

我偶然发现了 SQL Azure 中的一个问题,其中Sort-operator 由于行估计不佳而溢出到 TempDB 中。

  • 我们正在查询与多个明细表连接的主表
  • 该表使用TenantId-column 对每个租户的表进行分区
  • 有些租户有 10,000 行,有些只有 100 行。
  • 有一个行级安全策略,可以为FILTER PREDICATE上述所有查询添加一个TenantId
  • 查询由 .NET 应用程序中的实体框架生成
  • 所有索引统计数据都是最新的
  • 所有明细表行都通过Index Seeks检索

问题

由于租户之间的行数差异很大,基数估计器产生的估计值非常低。这与两个内部连接相结合,进一步减少了估计,使得实际产生 3600 行的查询预计只产生 3。这是 3 个数量级的下降。

我尝试了什么?

  1. Filtered Statistics为那些产生大量行的键值定义,作为对 CE 的额外提示。
  2. 在处理参数化查询时遇到了限制。这OPTION ( RECOMPILE )适用于某些谓词,但不适用于TenantId通过上述安全策略注入的谓词。
  3. 内联过滤器谓词,因此我们在同一列上有效过滤两次有效,但似乎......至少可以说是多余的
  4. INNER JOINs更改为s 可以LEFT OUTER JOIN改善错误连接估计,但由于我们使用实体框架,我更喜欢不需要更改查询的解决方案。注意:显然,如果唯一的方法是重写查询,那么这就是我们将要走的路线。

其他想法

  • 我曾考虑过添加一个包含 10 万条记录的虚拟租户来抵消估计值的想法,这样行估计值至少对于最大的真实租户来说足够大,但这会使我们对小租户的估计过高。

我在寻找什么?

  • 我做错了什么 - 我把自己画到了一个角落里吗?
  • 有没有我可以考虑的替代方案?

我欢迎您的任何想法,谢谢!


排序运算符用于分页。我实际上不想检索所有行。所以简而言之,排序需要发生在数据库中(而不是在应用程序中)。

另外,要明确的是,这里的问题不是 EF 生成的查询。这是一个简单的查询,带有许多INNER/ …

sql-server statistics azure-sql-database cardinality-estimates

10
推荐指数
1
解决办法
540
查看次数