标签: statistics

随着时间的推移保持一致的查询性能

我们正在对具有大量数据的 SQL Server 数据库运行密集的应用程序负载(数千次操作/秒)。有些表有数十亿行,其中一些有大量插入和更新。

DB 性能一般都还可以,但我们会时不时地遇到查询性能问题;以前运行良好的相当简单的查询可能会突然花费 10-100 倍的时间。

这似乎与表/索引统计信息和查询优化器有关 - 大多数情况下,统计信息更新将解决问题,然后再次更新统计信息会使情况变得更糟(然后重新运行统计信息更新通常会解决问题最终)。

似乎正在发生的事情是优化器决定对某些查询使用客观错误的索引;突然之间,在使用了正确的方法数天和数周之后。

我的问题是:为什么会发生这种情况,我们能做些什么?

这个数据库已经运行了多年,负载基本相同,查询几乎相同,更新量也相同。对于 99.995% 的查询,应该没有理由随着时间的推移决定不同的索引策略,无论输入如何(而且 - 实际上 - 这样做会明显地完全破坏查询性能)。

如上所述,按计划自动更新统计数据通常会产生可怕的问题——如果统计样本出现偏差(这似乎至少有 5% 的情况发生),我们最终会陷入痛苦的世界。

有没有办法告诉SQL Server(在某些表上)统计直方图和密度不会随时间变化,所以请继续对涉及该表的查询使用相同的查询计划?如果不是,我们如何确保随着时间的推移统计更新的可预测结果(避免上述的偏斜统计问题)?

没有存储过程。我们确实可以控制 SQL,因此它可能会被更改,但它有很多代码,因此如果我们必须更改每个查询(例如添加附加子句),那将是不幸的。

一个后续问题:参数嗅探似乎只与存储过程相关,对吗?

sql-server optimization statistics

7
推荐指数
1
解决办法
528
查看次数

为什么集群列存储上的统计信息更新速度比行存储上慢?

我已经将几个大型表(每个都有 >10^9 行和几十列)从 SQL Server 2014 实例上的聚集行存储移动到聚集列存储索引,并注意到这些表上的统计信息更新(默认采样,在我们的 ETL 中触发)或来自 Hallengren 脚本)现在需要更长的时间。

一个更具理论性的问题是为什么会这样?我的疯狂猜测是,统计信息更新会产生大量随机读取,这与列存储索引不能很好地配合,因为它们更适合大量数据的顺序读取。我很高兴知道更“深入”的解释。

更重要的问题是我是否可以做点什么来反对它。我已经在 SQL Server 2017 实例上尝试了针对具有单个 bigint 列(见下文)的表的测试用例,得到了相同的结果。增量统计在纸面上似乎是一个很好的解决方案。我需要重新创建所有统计对象(目前不是增量的,可能是由于历史原因),扩展 ETL 逻辑并更新我们的 Hallengren 脚本版本(我们目前使用旧版本)。如果有人能在我进入这个兔子洞之前分享他/她的经验,我将不胜感激。

重现步骤:

/*Create a rowstore and a columnstore table with a single bigint column*/
CREATE TABLE dbo.rowstore (col1 BIGINT);
GO

CREATE TABLE dbo.columnstore (col1 BIGINT);
GO

CREATE CLUSTERED COLUMNSTORE INDEX CCI_columnstore ON dbo.columnstore;
GO

/*Fill both tables with 400 * 10^6 rows. This results in a 15GB large rowstore and a 3,1GB large columnstore tables*/
;WITH e1(n) AS …
Run Code Online (Sandbox Code Playgroud)

sql-server statistics columnstore sql-server-2014 sql-server-2017

7
推荐指数
1
解决办法
1141
查看次数

SQL Server 主键列统计直方图建议重复值

我有一个关于表中主键列的统计信息。当我使用默认选项更新统计信息时:

UPDATE STATISTICS dbo.MyTable PK__MyTable__CB394B3946083350
Run Code Online (Sandbox Code Playgroud)

我得到一个直方图如下(删节)

                    RANGE_HI_KEY                      RANGE_ROWS                         EQ_ROWS             DISTINCT_RANGE_ROWS                  AVG_RANGE_ROWS
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
                      3400002201                               0                               1                               0                               1
                      3400009992                        18103.04                               1                            7790                        2.323882
                      3400040033                        26083.68                               1                           26080                        1.000144
                      3400050456                        13029.09                               1                           10422                        1.250153
                      3400087676                        26083.68                               1                           26080                        1.000144
                      3400103858                        19556.38                               1                           16181                        1.208602
                      3400126866                        13029.09                               1                           13029                               1
                      3400162832                        39138.27                               1                           35965                        1.088232
                      3400213115                        45665.56                               1                           45641                        1.000547
                      3400238444                        26083.68                               1                           25328                        1.029836
                      3400242626                        13029.09                               1                            4181                        3.116262
                      3400262174                        19556.38                               1                           19547                         1.00048
                      3400283983                        26083.68                               1                           21808                         1.19606
                      3400304837                        19556.38                               1 …
Run Code Online (Sandbox Code Playgroud)

sql-server primary-key statistics index-statistics sql-server-2019

7
推荐指数
1
解决办法
173
查看次数

估计mysql中行访问的分布

我试图了解一个相当大的表的“热数据”部分的大小,我想知道这是否可以直接在 mysql 中完成。我知道使用 percona 版本的 mysql,我可以访问诸如“每个表访问的行数”之类的数字,但我实际上需要每行这些数据(例如,id 为 1 的行被读取 200 次,行id 2 被读取 300 次,其中 id 是自动增量列)

mysql statistics

6
推荐指数
1
解决办法
857
查看次数

获取 MS SQL Server 中列的 NULL 统计信息

在 MS SQL Server 2005 中,如何提取给定列的 NULL 分数(或 NULL 计数)的统计信息?

Oracle 和 PostgreSQL 中也有同样的信息,听说 MS SQL 也有统计数据,但不知道在哪里可以找到。谷歌没有多大帮助。

我希望我会听到类似的话

SELECT null_frac FROM pg_stats WHERE tablename='mytab' and attname='mycol';
/* PostgreSQL, stats gathered by ANALYZE */
Run Code Online (Sandbox Code Playgroud)

或者

SELECT nullcnt FROM custom_stats_table WHERE tabname='MYTAB' and colname='MYCOL';
/* Oracle, stats gathered by dbms_stats.get_column_stats */
Run Code Online (Sandbox Code Playgroud)

我不是在问如何自己计算这些值——我知道该怎么做。我需要数千列的这些统计信息,并且在我正在处理的数据库上计算这将花费很长时间。我需要近似值,它们应该在服务器中的某个地方 - 基于成本的优化器无论如何都需要它们。

sql-server-2005 sql-server statistics

6
推荐指数
1
解决办法
1285
查看次数

什么会导致统计数据脱节?

我刚刚解决了客户站点上的一个问题,结果证明这是由于统计错误导致优化器超时。运行exec sp_updatestats解决了这个问题,现在一切都很好。

我现在有点困惑的是,统计数据最初是如何脱节的?

数据库同时打开了 auto_create_stats 和 auto_update_stats。所以 SQL Server 应该在没有任何干预的情况下保持最新的统计信息。

那么为什么它在这种情况下失败了呢?

该客户最近升级了他们的数据库服务器。他们自己处理,所以我不确定他们经历了什么程序,但我无法想象这比在旧服务器上备份数据库并在新服务器上恢复数据库更复杂。这可能以某种方式导致故障吗?

sql-server statistics

6
推荐指数
1
解决办法
1437
查看次数

AUTO_UPDATE_STATISTICS_ASYNC 开启?

有人建议我设置AUTO_UPDATE_STATISTICS_ASYNC ON可能是个好主意。我一直在阅读一些想法,但仍然不确定,因为这是一个非默认设置。

有什么进一步的建议吗?

sql-server statistics

6
推荐指数
1
解决办法
578
查看次数

SQL Server - Varbinary 列 - 统计更新速度极慢

我的数据库中有一个表,我们用作文件存储,文件本身存储在一个varbinary列中,直到最近这一切似乎都运行良好,我们注意到该表的一个实例基本上“卡住”了插入语句.

检查sys.dm_os_waiting_tasks显示插入语句触发了统计更新,并且此统计更新花费了长时间。(17 分钟)。

这是我们发现运行的语句:

SELECT StatMan([SC0], [LC0]) FROM 
   (SELECT TOP 100 PERCENT CONVERT([varbinary](200), 
        SUBSTRING ([Data], 1, 100)++substring([Data], 
        case when LEN([Data])<=200 then 101 else 
        LEN([Data])-99 end, 100)) AS [SC0], 
        datalength([Data]) AS [LC0] 
    FROM [FileSystem].[FileData] WITH 
    (READUNCOMMITTED) ORDER BY [SC0] ) AS _MS_UPDSTATS_TBL
Run Code Online (Sandbox Code Playgroud)

该表中大约有 2000 行,如下所示:

CREATE TABLE [FileSystem].[FileData]
(
[Id] [uniqueidentifier] NOT NULL CONSTRAINT [DF__FileData__Id__09DE7BCC] DEFAULT     (newsequentialid()),
[Data] [varbinary] (max) NULL,
[FileHash] [nvarchar] (4000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[FileSize] [bigint] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] …
Run Code Online (Sandbox Code Playgroud)

statistics sql-server-2008-r2 varbinary

6
推荐指数
1
解决办法
6164
查看次数

创建/更新统计信息对事务日志有影响吗?

假设在一个大表上创建或更新统计信息是否会产生显着(或根本没有)的事务日志流失?我认为不会,因为它不会改变底层数据或结构。

如果是这样,什么是验证的好方法?

sql-server statistics transaction-log

6
推荐指数
1
解决办法
2830
查看次数

即使新查询的逻辑读取比旧查询少,它也更慢

我在存储过程中有一个查询,它必须列出一个范围内的所有日期,并从表中加入日期(如果当天存在的话)。

这个过程是在我成为DBA之前创建的,所以我想我可以优化一下。但是,我似乎碰到了一堵砖墙,我不明白为什么。

过程的当前实现从两个普通表(我们称它们为 TableA 和 TableB)中作为派生查询(在 FROM 子句中)中选择数据,然后将其作为 RIGHT JOIN 放在上面:

RIGHT JOIN (
     SELECT DATEADD(DAY,number,@DateFrom) AS DATE
     FROM (
         SELECT DISTINCT number
         FROM master.dbo.spt_values
         WHERE name IS NULL
     ) n
     WHERE DATEADD(DAY,number,@DateFrom) <= @DateTo
) AS y ON derived.Date = y.Date -- "derived" is an alias of the derived query
Run Code Online (Sandbox Code Playgroud)

由于在多个过程中使用了相同的代码,我想我会创建一个日期从 2005-01-01 到 2039-01-01 的表:

CREATE TABLE Dates(
     [Date] DATE NOT NULL PRIMARY KEY
)
Run Code Online (Sandbox Code Playgroud)

该表是从具有日期维度的仓库中填充的。

所以,我写的不是那个 RIGHT JOIN,而是:

FROM Dates d
LEFT JOIN derived ON derived.Date …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization statistics

6
推荐指数
1
解决办法
1338
查看次数