从 “盲调” 到 “精准优化”:SQL Server 表统计信息实战指南

本文核心要旨在于:SQL Server 表统计信息作为元数据对象,宛如数据分布的 "指南针",精准存储着数据分布信息,为查询优化器提供关键依据,助力其生成高效的查询执行计划。在维护方面,统计信息更新有手动与自动两种模式可供选择。手动更新可通过特定指令精准把控,自动更新则借助数据库引擎的智能机制自动完成,而更新频率需综合考量数据波动性等多方面因素。

在采样策略上,不同规模的表有其适配方案。小表数据量有限,采用 FULLSCAN 能全面且精准地收集信息;中表以 50% 的采样率,在效率与准确性间寻得平衡;大表至少 25% 的采样率,可在庞大的数据量中高效获取关键特征。

统计信息管理也有诸多最佳实践,如启用自动更新以保证信息实时性,将统计信息维护与索引维护同步进行,提升整体性能。

数据库统计信息是 SQL Server 达成最优查询性能的根基。深入理解其工作机制,正确开展维护工作并精准把握更新时机,能大幅提升数据库性能。定期维护统计信息应成为数据库管理员(DBA)日常工作的重要组成,合理的管理能让优化器获取精准数据,生成高效执行计划,实现查询响应加速与资源利用优化。

从 "盲调" 到 "精准优化":SQL Server 表统计信息实战指南

image

一、引言

SQL Server 表统计信息指导优化器生成高效的查询计划,数据库管理员(DBA)必须保持其更新,以避免因数据过时导致的性能问题。

二、什么是 SQL Server 表统计信息?

  1. 定义与重要性 在 SQL Server 中,表统计信息是元数据对象,用于存储表中一列或多列的数据分布信息。这些统计信息对查询优化器至关重要,优化器通过它进行基数估计,这是生成优质执行计划的基础。例如,当查询过滤列存在数据分布倾斜时,优化器可借助统计信息选择更高效的访问方式。保持统计信息更新是维持查询性能的核心,底层数据大量变化会使统计信息过时,导致优化器做出错误基数估计,生成低效执行计划。可通过UPDATE STATISTICS手动更新或启用AUTO_UPDATE_STATISTICS自动更新功能。
  2. 统计信息包含的核心内容 统计信息是轻量级对象,由头部信息和数据分布直方图组成,存储表中的总行数、平均键长度、列间的数据分布情况、最常见值和最不常见值的信息等元数据。
  3. 统计信息对优化器的作用 优化器通过统计信息估算查询可能返回的行数、判断哪些索引可能适用、确定最优的连接策略。

三、统计信息在查询性能中的关键作用

统计信息对数据库性能至关重要,能帮助查询优化器生成高效执行计划、决定何时使用特定索引、实现准确的基数估计、指导连接策略和连接顺序的选择。缺乏准确统计信息,查询优化器会生成次优执行计划,导致性能下降。

四、统计信息如何提升查询性能?

查询优化器利用统计信息估算查询谓词的选择性。以SELECT * FROM Customers WHERE Region = 'North' AND AnnualSpend > 50000查询为例,若RegionAnnualSpend列统计信息准确,优化器可估算返回行数、选择合适访问方式和确定最优连接顺序。

五、统计信息采样及其重要性

统计信息采样是 SQL Server 收集数据分布信息的方式。对于大型表,采用统计采样算法、分析数据子集构建直方图,在准确性和性能影响之间取得平衡。默认采样率由 SQL Server 自动确定,也可手动指定,如UPDATE STATISTICS Sales.Orders WITH SAMPLE 50 PERCENT;

六、统计信息维护:多久更新一次?

  1. 更新频率影响因素 当底层数据发生显著变化时,统计信息会过时。更新频率需根据数据波动性、查询性能要求和维护窗口确定。
  2. 通用维护指南 高波动性 OLTP 系统每日更新;中等变化的数据仓库每周更新;执行批量操作后和查询性能突然下降时也需更新。
  3. 自动更新触发条件 当启用自动更新统计信息(默认开启)、约 20% 的行发生变化(阈值随表大小调整)、表基数从 0 变为大于 0 时,SQL Server 会自动更新统计信息。

七、实践示例:统计信息的创建、查询与分析

步骤 1:创建测试表并插入数据
创建测试数据库StatsDemo,创建测试表dbo.OrderData并插入带有倾斜分布的 100,000 行数据。

-- 创建测试数据库
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'StatsDemo')
BEGINCREATE DATABASE StatsDemo;
END
GOUSE StatsDemo;
GO-- 创建测试表
IF OBJECT_ID('dbo.OrderData', 'U') IS NOT NULLDROP TABLE dbo.OrderData;CREATE TABLE dbo.OrderData
(OrderID INT IDENTITY(1,1) PRIMARY KEY,CustomerID INT NOT NULL,OrderDate DATE NOT NULL,Region VARCHAR(20) NOT NULL,ProductCategory VARCHAR(50) NOT NULL,Amount DECIMAL(12,2) NOT NULL
);-- 插入带有倾斜分布的测试数据(共100,000行)
-- 注意:Region列80%为'East',Amount列按地区有不同分布
DECLARE @i INT = 1;
DECLARE @regions TABLE (Region VARCHAR(20), Probability DECIMAL(5,2));
INSERT INTO @regions VALUES ('East', 0.80), ('West', 0.10), ('North', 0.05), ('South', 0.05);DECLARE @categories TABLE (Category VARCHAR(50), Probability DECIMAL(5,2));
INSERT INTO @categories VALUES ('Electronics', 0.30), ('Clothing', 0.25), ('Home Goods', 0.20),('Groceries', 0.15),('Sporting Goods', 0.10);BEGIN TRANSACTION;WHILE @i <= 100000
BEGIN-- 按概率生成RegionDECLARE @region VARCHAR(20) = (SELECT TOP 1 Region FROM @regions ORDER BY CASE WHEN RAND() <= Probability THEN 0 ELSE 1 END, NEWID());-- 按概率生成ProductCategoryDECLARE @category VARCHAR(50) = (SELECT TOP 1 Category FROM @categories ORDER BY CASE WHEN RAND() <= Probability THEN 0 ELSE 1 END, NEWID());-- 按地区生成Amount(不同地区分布不同)DECLARE @amount DECIMAL(12,2);IF @region = 'East' SET @amount = 500 + (RAND() * 500);ELSE IF @region = 'West' SET @amount = 1000 + (RAND() * 1000);ELSE IF @region = 'North' SET @amount = 750 + (RAND() * 250);ELSE SET @amount = 250 + (RAND() * 750);-- 插入数据INSERT INTO dbo.OrderData (CustomerID, OrderDate, Region, ProductCategory, Amount)VALUES (CAST((RAND() * 1000) AS INT), -- CustomerID(1-1000)DATEADD(DAY, -CAST((RAND() * 365) AS INT), GETDATE()), -- 过去一年的随机日期@region,@category,@amount);SET @i = @i + 1;
ENDCOMMIT;

步骤 2:无统计信息时运行查询并分析性能
禁用自动统计信息并清除现有统计信息,运行查询并查看执行计划。

-- 临时禁用自动创建和更新统计信息
ALTER DATABASE StatsDemo SET AUTO_CREATE_STATISTICS OFF;
ALTER DATABASE StatsDemo SET AUTO_UPDATE_STATISTICS OFF;-- 删除现有统计信息(仅删除自动创建的_WA开头统计信息)
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql = @sql + 'DROP STATISTICS dbo.OrderData.' + name + ';'
FROM sys.stats
WHERE object_id = OBJECT_ID('dbo.OrderData')
AND name LIKE '_WA%';EXEC sp_executesql @sql;-- 启用SSMS中的实际执行计划
-- 开启IO和时间统计
SET STATISTICS IO ON;
SET STATISTICS TIME ON;SELECT * FROM dbo.OrderData
WHERE Region = 'West' AND Amount > 1500;SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

步骤 3:创建统计信息并对比性能
WHERE子句中的列创建统计信息,再次运行相同查询,性能提升原因是优化器能更准确估算返回行数并选择更优执行计划。

-- 为WHERE子句中的列创建统计信息(全表扫描收集数据)
CREATE STATISTICS Stats_Region ON dbo.OrderData(Region) WITH FULLSCAN;
CREATE STATISTICS Stats_Amount ON dbo.OrderData(Amount) WITH FULLSCAN;-- 再次运行相同查询
SET STATISTICS IO ON;
SET STATISTICS TIME ON;SELECT * FROM dbo.OrderData
WHERE Region = 'West' AND Amount > 1500;SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

步骤 4:查看统计信息详情
查看统计信息的直方图等详情和元数据,返回信息包括直方图信息、最后更新时间、采样行数、修改计数器等。

-- 查看统计信息的直方图等详情
DBCC SHOW_STATISTICS('dbo.OrderData', 'Stats_Region');
DBCC SHOW_STATISTICS('dbo.OrderData', 'Stats_Amount');-- 查看统计信息元数据
SELECTOBJECT_NAME(s.object_id) AS TableName,s.name AS StatisticsName,s.stats_id,s.auto_created, -- 是否自动创建s.user_created, -- 是否用户创建s.no_recompute, -- 是否禁止自动更新sp.last_updated, -- 最后更新时间sp.rows, -- 表总行数sp.rows_sampled, -- 采样行数sp.steps, -- 直方图步数sp.unfiltered_rows, -- 未过滤行数sp.modification_counter -- 上次更新后的修改次数
FROM sys.stats s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
WHERE s.object_id = OBJECT_ID('dbo.OrderData');

步骤 5:测试不同采样率的影响
测试不同采样率,不同采样率会导致直方图详情不同,FULLSCAN能提供最准确统计信息但消耗更多资源。

-- 测试10%采样率
UPDATE STATISTICS dbo.OrderData Stats_Region WITH SAMPLE 10 PERCENT;
DBCC SHOW_STATISTICS('dbo.OrderData', 'Stats_Region');-- 测试全表扫描采样
UPDATE STATISTICS dbo.OrderData Stats_Region WITH FULLSCAN;
DBCC SHOW_STATISTICS('dbo.OrderData', 'Stats_Region');

步骤 6:模拟数据变化并观察统计信息过时影响
模拟数据变化,用过时统计信息运行查询可能生成次优计划,更新统计信息后性能应提升。

-- 模拟大量数据变化(插入更多'West'地区的数据,改变分布)
INSERT INTO dbo.OrderData (CustomerID, OrderDate, Region, ProductCategory, Amount)
SELECTCAST((RAND() * 1000) AS INT),DATEADD(DAY, -CAST((RAND() * 365) AS INT), GETDATE()),'West','Electronics',1500 + (RAND() * 1000)
FROM sys.objects
CROSS JOIN sys.columns
WHERE object_id % 1000 = 0;-- 查看修改计数器和变化比例
SELECTOBJECT_NAME(s.object_id) AS TableName,s.name AS StatisticsName,sp.modification_counter,sp.rows,CAST(sp.modification_counter * 100.0 / sp.rows AS DECIMAL(5,2)) AS PercentChanged
FROM sys.stats s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
WHERE s.object_id = OBJECT_ID('dbo.OrderData');-- 用过时统计信息运行查询(可能生成次优计划)
SET STATISTICS IO ON;
SET STATISTICS TIME ON;SELECT * FROM dbo.OrderData
WHERE Region = 'West' AND Amount > 1500;SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;-- 更新统计信息
UPDATE STATISTICS dbo.OrderData WITH FULLSCAN;-- 用新统计信息运行查询(性能应提升)
SET STATISTICS IO ON;
SET STATISTICS TIME ON;SELECT * FROM dbo.OrderData
WHERE Region = 'West' AND Amount > 1500;SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;

八、统计信息管理最佳实践

  1. 启用自动创建和更新:大多数环境下建议开启。
ALTER DATABASE StatsDemo SET AUTO_CREATE_STATISTICS ON;
ALTER DATABASE StatsDemo SET AUTO_UPDATE_STATISTICS ON;
  1. 与索引维护同步:将统计信息维护纳入常规数据库维护。
-- 示例维护脚本(全表扫描更新)
UPDATE STATISTICS dbo.OrderData WITH FULLSCAN;
  1. 针对不同表选择采样率
    • 小表(<10 万行):使用FULLSCAN
    • 中表:50% 采样率。
    • 大表:至少 25% 采样率。
  2. 批量操作后更新
-- 批量插入或数据仓库加载后执行
UPDATE STATISTICS SchemaName.TableName;

监控统计信息时效性

-- 查看指定表的统计信息更新时间
SELECT OBJECT_NAME(object_id) AS TableName, name AS StatsName, STATS_DATE(object_id, stats_id) AS LastUpdated
FROM sys.stats
WHERE OBJECT_NAME(object_id) = 'YourTableName'
ORDER BY LastUpdated;

高波动性表特殊处理:对修改集中的高波动表,增加更新频率。

九、总结

强调数据库统计信息对 SQL Server 查询性能的重要性,呼吁 DBA 定期维护统计信息,以实现更快查询响应和更优资源利用率。

十、扩展链接

Wyn 商业智能 ------ 选择 Microsoft SQL Server 作为主数据库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909758.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

别的摄像机都能国标GB28181注册上,就这台海康摄像机注册不上来,国标配置都反复检查没问题

别的摄像机都能国标GB28181注册上,就这台海康摄像机注册不上来,国标配置都反复检查没问题先看看下午EasyGBS群里用户提到的问题,我先大概描述一下,用户说有一台海康的摄像机IPC国标注册不到EasyGBS,另一台可以,区…

保护眼睛小程序

import wx import time from datetime import datetime, timedelta class MyFrame(wx.Frame): def init(self): super().init(None, title=用眼提醒, size=wx.Size(800, 600)) self.SetWindowStyle(wx.STAY_ON_TOP)# 创…

公司有网站域名 如何做网站传媒公司做网站编辑 如何

同一个浏览器登录不同账号session一致&#xff0c;这就导致后面登录的用户数据会把前面登录的用户数据覆盖掉&#xff0c;这个问题很常见&#xff0c;当前我这边解决的就是同一个浏览器不同窗口只能登录一个用户&#xff0c;解决方案如下&#xff1a; 1、在App.vue中监听本地数…

石家庄网站外包有多少种做网站后台程序

Java 集合交集判断 一. 使用 retainAll()方法二. 使用 removeAll() 方法与判断集合大小三. 使用 Stream 流式处理四. 使用 Collections.disjoint() 方法五. 总结六. 参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续…

视频网站做板块栏目手机大全网站

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-31&#xff09;山西电力市场全天平均日前电价为445.23元/MWh。其中&#xff0c;最高日前电价为791.27元/MWh&#xff0c;预计出现在08:15。最低日前电价为270.52元/MWh&#xff0c;预计…

做的网站上传到服务器专业制作效果图公司

今天给大家分享的题目是leetcode242有效的字母异位词 我们先看题目描述&#xff1a; Chatgpt中对于字母异位词的解释如下&#xff1a; 字母异位词是指由相同的字母组成但顺序不同的单词。换句话说&#xff0c;字母异位词具有相同的字母&#xff0c;只是排列顺序不同。 简单的将…

备案可以不关闭网站吗科技设计网站建设

排序思想掌握 前言&#xff1a; 开发当中为什么会用到算法&#xff1f;或者说为什么需要算法与数据结构等&#xff1f; 算法思想可以帮助我们优化程序的性能&#xff0c;例如减少时间与空间复杂度&#xff0c;从而使程序更快、更有效地运行。在数据分析领域&#xff0c;算法思想…

做模具做什么网站做外贸的人经常用什么网站

Zookeeper 架构理解 整体架构 Follower server 可以直接处理读请求&#xff0c;但不能直接处理写请求。写请求只能转发给 leader server 进行处理。最终所有的写请求在 leader server 端串行执行。&#xff08;因为分布式环境下永远无法精确地确认不同服务器不同事件发生的先后…

做网站维护有危险吗官网制作需要多少钱

uniapp嵌套webview&#xff0c;如何解决回退问题&#xff1f; 文章目录 uniapp嵌套webview&#xff0c;如何解决回退问题&#xff1f;遇到问题解决方式方式一方式二 场景&#xff1a; 进入首页&#xff0c;自动跳转第三方应用 遇到问题 在设备上运行时&#xff0c;无法回退上…

杭州滨江的网站建设公司众筹 wordpress

每次刚装完系统我们访问GitHub就会出现无法访问的情况&#xff0c;此时只需要修改host文件将可访问的dns解析地址写入进去即可。 查询DNS 使用dns监测查询工具 https://tool.chinaz.com/dns https://dnsdaquan.com/ 输入无法访问的IP github.com 进行检测 查询到可访问的i…

如何创建外卖网站优秀广告设计案例作品欣赏

压缩包的内容 里面有secret.txt文件&#xff0c;用ARCHPR工具套上字典&#xff0c;爆破压缩包密码。密码为pavilion 解压得到原图&#xff0c;并且有了加密后的图片&#xff0c;根据代码里的key和参数直接运行脚本解密水印图片&#xff1a; import cv2 import numpy as np imp…

贵州专业网站建设公司如果做公司网站

写在前面&#xff1a; 博主本人大学期间参加数学建模竞赛十多余次&#xff0c;获奖等级均在二等奖以上。为了让更多学生在数学建模这条路上少走弯路&#xff0c;故将数学建模常用数学模型算法汇聚于此专栏&#xff0c;希望能够对要参加数学建模比赛的同学们有所帮助。 目录 1. …

[::-1]的用法

[::-1] 是 Python 中一种非常简洁且常用的切片(slice)语法,它的作用是反转序列。 它可以用在多种数据类型上,包括:列表 (list) 字符串 (string) 元组 (tuple) NumPy 数组语法解析 切片语法的一般形式是:[start:s…

003_for循环操作列表和元组

1、for循环遍历整个列表 cars = ["奔驰", "比亚迪", "长安", "理想"] cars.insert(0, "红旗") cars.append("长安") cars.insert(len(cars), "宝马…

linux 文件传输命令

在 Linux 系统中,有多种命令可用于文件传输,适用于不同场景(本地传输、网络传输、不同协议等)。以下是常用的文件传输命令: 1. 本地文件传输命令 cp - 复制文件 / 目录 最基础的本地文件复制命令bash# 复制文件 c…

济南网站备案编写软件开发文档

2024年淘宝天猫618活动&#xff0c;将于2024年5月19日开始&#xff0c;今年618淘宝天猫取消了预售环节。同时&#xff0c;618淘宝天猫也提供了多项优惠活动&#xff1a;超级红包、跨店满减、官方立减、全程价保及草柴APP领优惠券拿购物返利等多重优惠活动。 2024年淘宝天猫618…

黑龙江省城乡建设厅网站首页高端app开发

1.进程间通信概述 UNIX系统IPC是各种进程通信方式的统称。 2.管道通信原理 特点&#xff1a; 1.它是半双工的&#xff08;即数据只能在一个方向上流动&#xff09;&#xff0c;具有固定的读端和写端。 2.它只能用于具有亲缘关系的进程之间通信&#xff08;也是父子进程或者…

济南网站开发公司价格比较网

Ragas是一个框架&#xff0c;它可以帮助你从不同的方面评估你的问答&#xff08;QA&#xff09;流程。它为你提供了一些指标来评估你的问答系统的不同方面&#xff0c;具体包括&#xff1a; 评估检索&#xff08;context&#xff09;的指标&#xff1a;提供了上下文相关性&…

网站建设国内外研究现状模板建模培训机构

yum or rpm&#xff1f;yum安装方式很方便&#xff0c;但是下载mysql的时候从官网下载&#xff0c;速度较慢。rpm安装方式可以从国内镜像下载mysql的rpm包&#xff0c;比较快。rpm也适合离线安装。环境说明•操作系统&#xff1a;Centos7.4 (CentOS-7-x86_64-Minimal-1804.iso)…