1. 首页 > SQLServer教程 > 正文

SQLServer教程FG089-SQLServer统计信息管理实战

本文档风哥主要介绍SQLServer数据库统计信息管理相关知识,包括SQLServer数据库统计信息规划、SQLServer数据库统计信息实施方案、SQLServer数据库统计信息配置、SQLServer数据库统计信息验证等内容,风哥教程参考SQLServer官方文档统计信息管理内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

Part01-基础概念与理论知识

1.1 SQLServer数据库统计信息概念

SQLServer统计信息是关于表或索引中数据分布的元数据,用于查询优化器生成最佳执行计划。统计信息包含列值的分布情况、直方图、密度信息等,帮助查询优化器估计查询结果的行数和成本,从而选择最优的执行计划。统计信息是SQLServer查询优化的重要组成部分,准确的统计信息可以显著提高查询性能。更多视频教程www.fgedu.net.cn

SQLServer数据库统计信息的重要性:

  • 帮助查询优化器生成最佳执行计划
  • 提高查询性能
  • 减少查询执行时间
  • 降低系统资源消耗
  • 提升应用程序用户体验

1.2 SQLServer数据库统计信息类型

# SQLServer数据库统计信息类型

1. 自动创建的统计信息
– 由SQLServer自动创建
– 基于查询的过滤条件
– 名称以_WA_Sys_开头
– 适用于临时查询

2. 手动创建的统计信息
– 由DBA手动创建
– 可以指定统计信息名称
– 可以自定义统计信息参数
– 适用于特定查询模式

3. 索引统计信息
– 自动为索引创建
– 基于索引键列
– 与索引关联
– 索引重建时自动更新

4. 列统计信息
– 基于表中的列
– 可以是单列或多列
– 帮助优化器估计选择性
– 适用于非索引列

5. 过滤统计信息
– 基于WHERE子句创建
– 只包含满足条件的数据
– 提高统计信息精度
– 适用于数据分布不均匀的列

# 统计信息组成

1. 直方图
– 显示列值的分布
– 包含边界值和频率
– 帮助优化器估计选择性
– 用于点查询和范围查询

2. 密度信息
– 显示列值的唯一性
– 用于估计JOIN操作的结果集大小
– 帮助优化器选择JOIN类型
– 影响JOIN顺序的选择

3. 统计信息元数据
– 统计信息名称
– 创建时间
– 更新时间
– 采样率
– 行数

# 统计信息更新触发条件

1. 自动更新触发条件
– 表大小 < 500行:每次修改都可能触发 - 表大小 >= 500行:修改行数达到500 + 20%时触发
– 大型表:修改行数达到2000 + 0.2%时触发

2. 手动更新
– 使用UPDATE STATISTICS命令
– 可以指定采样率
– 可以更新特定统计信息
– 可以在维护窗口执行

1.3 SQLServer数据库统计信息优势

SQLServer数据库统计信息优势:

  • 提高查询性能:帮助查询优化器生成最佳执行计划
  • 减少I/O操作:选择更高效的执行路径
  • 降低CPU使用:减少不必要的计算
  • 提高系统并发:减少查询执行时间,增加并发处理能力
  • 改善用户体验:快速响应查询,提升应用性能
风哥提示:统计信息是SQLServer查询优化的关键,准确的统计信息可以显著提高查询性能,建议定期更新统计信息,确保查询优化器使用最新的数据分布信息。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 SQLServer数据库统计信息规划

SQLServer数据库统计信息规划要点:

# 统计信息规划步骤

1. 需求分析
– 分析查询模式:点查询、范围查询、JOIN操作等
– 识别高频查询:经常执行的查询语句
– 评估数据分布:数据的分布情况和唯一性
– 分析表大小:表的大小和增长趋势

2. 统计信息设计
– 选择统计信息类型:自动、手动、索引、过滤等
– 确定统计信息列:基于查询的过滤条件和JOIN条件
– 考虑统计信息采样率:根据数据分布情况
– 设计过滤统计信息:对于数据分布不均匀的列

3. 更新策略
– 自动更新:启用自动统计信息更新
– 手动更新:定期手动更新统计信息
– 更新频率:根据数据修改频率确定
– 更新时间:选择系统负载较低的时间

4. 监控策略
– 监控统计信息状态:查看统计信息更新时间
– 监控查询性能:识别因统计信息过期导致的性能问题
– 监控执行计划:分析执行计划变化
– 建立性能基线:比较优化前后的性能

5. 实施计划
– 优先级排序:按表的重要性和查询频率排序
– 实施步骤:分阶段实施统计信息管理
– 测试计划:验证统计信息更新效果
– 回滚策略:准备回滚方案

# 规划参考

表类型 数据量 更新频率 采样率 监控频率
————————————————————————
OLTP表 < 1000万行 每天 20% 每周 OLAP表 > 1000万行 每周 10% 每月
小型表 < 100万行 每周 50% 季度 大型表 > 1亿行 每两周 5% 每月

2.2 SQLServer数据库统计信息实施方案

SQLServer数据库统计信息实施方案:

# 统计信息实施方案

1. 启用自动统计信息更新
– 数据库级别启用:ALTER DATABASE SET AUTO_UPDATE_STATISTICS ON
– 异步更新:ALTER DATABASE SET AUTO_UPDATE_STATISTICS_ASYNC ON
– 自动创建:ALTER DATABASE SET AUTO_CREATE_STATISTICS ON
– 验证设置:SELECT * FROM sys.databases WHERE name = ‘fgedudb’

2. 手动更新统计信息
– 更新所有统计信息:UPDATE STATISTICS table_name
– 更新特定统计信息:UPDATE STATISTICS table_name statistic_name
– 指定采样率:UPDATE STATISTICS table_name WITH SAMPLE 20 PERCENT
– 全扫描:UPDATE STATISTICS table_name WITH FULLSCAN

3. 创建统计信息
– 创建单列统计信息:CREATE STATISTICS statistic_name ON table_name (column_name)
– 创建多列统计信息:CREATE STATISTICS statistic_name ON table_name (column1, column2)
– 创建过滤统计信息:CREATE STATISTICS statistic_name ON table_name (column_name) WHERE condition
– 指定采样率:CREATE STATISTICS statistic_name ON table_name (column_name) WITH SAMPLE 20 PERCENT

4. 监控统计信息
– 查看统计信息:SELECT * FROM sys.stats WHERE object_id = OBJECT_ID(‘table_name’)
– 查看统计信息详情:DBCC SHOW_STATISTICS(‘table_name’, ‘statistic_name’)
– 查看统计信息更新时间:SELECT name, update_date FROM sys.stats WHERE object_id = OBJECT_ID(‘table_name’)
– 监控统计信息使用情况:SELECT * FROM sys.dm_db_stats_properties(object_id(‘table_name’), stats_id)

5. 维护统计信息
– 重建索引时更新:ALTER INDEX ALL ON table_name REBUILD
– 重组索引时更新:ALTER INDEX ALL ON table_name REORGANIZE
– 定期更新:使用维护计划或作业
– 监控统计信息过期:识别长期未更新的统计信息

# 实施步骤参考

步骤 任务 负责人 时间
————————————————————
1 需求分析 DBA 1周
2 统计信息设计 DBA 3天
3 测试环境实施 DBA 2天
4 性能测试 测试团队 2天
5 生产环境实施 DBA 1天
6 监控配置 运维团队 1天
7 定期维护 DBA 每周

2.3 SQLServer数据库统计信息最佳实践

SQLServer数据库统计信息最佳实践:

  • 启用自动统计信息更新:确保统计信息能够自动更新
  • 定期手动更新统计信息:对于大型表或数据变化频繁的表
  • 使用适当的采样率:根据数据分布情况选择合适的采样率
  • 创建过滤统计信息:对于数据分布不均匀的列
  • 监控统计信息状态:定期检查统计信息更新时间
  • 在维护窗口更新统计信息:避免影响生产系统性能
  • 结合索引维护更新统计信息:在重建或重组索引时更新统计信息
  • 分析执行计划:识别因统计信息过期导致的执行计划问题
生产环境建议:统计信息实施方案应根据数据库的实际情况进行调整,建议在实施前进行充分测试,确保不会对系统性能造成负面影响。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 SQLServer数据库统计信息项目实施

3.1.1 SQLServer数据库统计信息环境准备

# 环境准备步骤

# 1. 检查SQLServer版本
SELECT @@VERSION;
GO

# 2. 创建测试数据库
CREATE DATABASE fgedu_stats;
GO

# 3. 创建测试表
USE fgedu_stats;
GO

CREATE TABLE dbo.fgedu_users (
id INT PRIMARY KEY IDENTITY,
username NVARCHAR(50) NOT NULL,
email NVARCHAR(100) NOT NULL,
create_time DATETIME DEFAULT GETDATE(),
status NVARCHAR(20) DEFAULT ‘Active’
);
GO

CREATE TABLE dbo.fgedu_orders (
id INT PRIMARY KEY IDENTITY,
user_id INT NOT NULL,
order_date DATETIME DEFAULT GETDATE(),
total_amount DECIMAL(10, 2) NOT NULL,
status NVARCHAR(20) DEFAULT ‘Pending’
);
GO

# 4. 插入测试数据
— 插入100万行用户数据
DECLARE @i INT = 1;
WHILE @i <= 1000000 BEGIN INSERT INTO dbo.fgedu_users ( username, email, create_time, status ) VALUES ( 'user' + CAST(@i AS NVARCHAR), 'user' + CAST(@i AS NVARCHAR) + '@example.com', DATEADD(DAY, @i % 365, '2023-01-01'), CASE @i % 3 WHEN 0 THEN 'Active' WHEN 1 THEN 'Inactive' ELSE 'Pending' END ); SET @i = @i + 1; END; GO -- 插入500万行订单数据 DECLARE @i INT = 1; WHILE @i <= 5000000 BEGIN INSERT INTO dbo.fgedu_orders ( user_id, order_date, total_amount, status ) VALUES ( ABS(CHECKSUM(NEWID())) % 1000000 + 1, DATEADD(DAY, @i % 365, '2023-01-01'), ABS(CHECKSUM(NEWID())) % 10000 + 1, CASE @i % 4 WHEN 0 THEN 'Pending' WHEN 1 THEN 'Processing' WHEN 2 THEN 'Shipped' ELSE 'Delivered' END ); SET @i = @i + 1; END; GO # 5. 检查初始统计信息 SELECT OBJECT_NAME(object_id) AS table_name, name AS stats_name, auto_created, user_created, no_recompute, last_updated FROM sys.stats WHERE object_id IN (OBJECT_ID('dbo.fgedu_users'), OBJECT_ID('dbo.fgedu_orders')); GO # 6. 测试初始查询性能 DECLARE @start_time DATETIME = GETDATE(); SELECT u.id, u.username, COUNT(o.id) AS order_count, SUM(o.total_amount) AS total_spent FROM dbo.fgedu_users u LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id WHERE u.create_time BETWEEN '2023-06-01' AND '2023-06-30' AND u.status = 'Active' GROUP BY u.id, u.username ORDER BY total_spent DESC TOP 100; DECLARE @end_time DATETIME = GETDATE(); SELECT 'Before stats update' AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms; GO

3.1.2 SQLServer数据库统计信息创建与更新

# 统计信息创建与更新步骤

# 1. 启用自动统计信息更新
— 启用自动统计信息更新
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS ON;
GO

— 启用异步统计信息更新
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS_ASYNC ON;
GO

— 启用自动创建统计信息
ALTER DATABASE fgedu_stats SET AUTO_CREATE_STATISTICS ON;
GO

# 2. 创建手动统计信息
— 为用户表创建统计信息
CREATE STATISTICS stats_fgedu_users_create_time_status
ON dbo.fgedu_users (create_time, status);
GO

— 为订单表创建统计信息
CREATE STATISTICS stats_fgedu_orders_user_id_order_date
ON dbo.fgedu_orders (user_id, order_date);
GO

— 创建过滤统计信息
CREATE STATISTICS stats_fgedu_users_status_active
ON dbo.fgedu_users (create_time)
WHERE status = ‘Active’;
GO

# 3. 查看统计信息
— 查看用户表的统计信息
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
auto_created,
user_created,
no_recompute,
last_updated
FROM sys.stats
WHERE object_id = OBJECT_ID(‘dbo.fgedu_users’);
GO

— 查看订单表的统计信息
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
auto_created,
user_created,
no_recompute,
last_updated
FROM sys.stats
WHERE object_id = OBJECT_ID(‘dbo.fgedu_orders’);
GO

# 4. 更新统计信息
— 更新用户表的所有统计信息
UPDATE STATISTICS dbo.fgedu_users;
GO

— 更新订单表的所有统计信息,使用全扫描
UPDATE STATISTICS dbo.fgedu_orders WITH FULLSCAN;
GO

— 更新特定统计信息,使用20%采样率
UPDATE STATISTICS dbo.fgedu_users stats_fgedu_users_create_time_status WITH SAMPLE 20 PERCENT;
GO

# 5. 查看统计信息详情
— 查看统计信息详情
DBCC SHOW_STATISTICS(‘dbo.fgedu_users’, ‘stats_fgedu_users_create_time_status’);
GO

— 查看统计信息直方图
DBCC SHOW_STATISTICS(‘dbo.fgedu_users’, ‘stats_fgedu_users_create_time_status’) WITH HISTOGRAM;
GO

— 查看统计信息密度
DBCC SHOW_STATISTICS(‘dbo.fgedu_users’, ‘stats_fgedu_users_create_time_status’) WITH DENSITY_VECTOR;
GO

# 6. 测试更新后的性能
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
AND u.status = ‘Active’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘After stats update’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

3.2 SQLServer数据库统计信息配置

3.2.1 SQLServer数据库统计信息参数优化

# 统计信息参数优化步骤

# 1. 配置数据库级统计信息设置
— 查看当前设置
SELECT
name,
is_auto_create_stats_on,
is_auto_update_stats_on,
is_auto_update_stats_async_on
FROM sys.databases
WHERE name = ‘fgedu_stats’;
GO

— 启用自动创建统计信息
ALTER DATABASE fgedu_stats SET AUTO_CREATE_STATISTICS ON;
GO

— 启用自动更新统计信息
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS ON;
GO

— 启用异步自动更新统计信息
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS_ASYNC ON;
GO

# 2. 配置统计信息采样率
— 使用全扫描更新统计信息
UPDATE STATISTICS dbo.fgedu_users WITH FULLSCAN;
GO

— 使用50%采样率更新统计信息
UPDATE STATISTICS dbo.fgedu_users WITH SAMPLE 50 PERCENT;
GO

— 使用10%采样率更新统计信息
UPDATE STATISTICS dbo.fgedu_users WITH SAMPLE 10 PERCENT;
GO

# 3. 配置统计信息更新频率
— 创建维护计划作业,定期更新统计信息
— 使用SQL Server Agent创建作业

# 4. 配置统计信息不自动重新计算
— 创建统计信息时指定不自动重新计算
CREATE STATISTICS stats_fgedu_users_username
ON dbo.fgedu_users (username)
WITH NORECOMPUTE;
GO

— 更改现有统计信息为不自动重新计算
UPDATE STATISTICS dbo.fgedu_users stats_fgedu_users_username WITH NORECOMPUTE;
GO

# 5. 监控统计信息配置
— 查看统计信息配置
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
auto_created,
user_created,
no_recompute,
last_updated
FROM sys.stats
WHERE object_id IN (OBJECT_ID(‘dbo.fgedu_users’), OBJECT_ID(‘dbo.fgedu_orders’));
GO

— 查看统计信息属性
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
modification_counter,
rows,
rows_sampled,
steps,
density
FROM sys.dm_db_stats_properties(object_id(‘dbo.fgedu_users’), stats_id)
JOIN sys.stats ON sys.dm_db_stats_properties.object_id = sys.stats.object_id
AND sys.dm_db_stats_properties.stats_id = sys.stats.stats_id
WHERE sys.stats.object_id = OBJECT_ID(‘dbo.fgedu_users’);
GO

3.2.2 SQLServer数据库统计信息维护

# 统计信息维护步骤

# 1. 识别过期统计信息
— 查找超过7天未更新的统计信息
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
last_updated,
DATEDIFF(DAY, last_updated, GETDATE()) AS days_since_update
FROM sys.stats
WHERE object_id IN (
SELECT object_id
FROM sys.objects
WHERE type = ‘U’
)
AND DATEDIFF(DAY, last_updated, GETDATE()) > 7
ORDER BY days_since_update DESC;
GO

# 2. 更新过期统计信息
— 更新所有过期统计信息
DECLARE @table_name NVARCHAR(128);
DECLARE @stats_name NVARCHAR(128);
DECLARE @sql NVARCHAR(MAX);

DECLARE stats_cursor CURSOR FOR
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name
FROM sys.stats
WHERE object_id IN (
SELECT object_id
FROM sys.objects
WHERE type = ‘U’
)
AND DATEDIFF(DAY, last_updated, GETDATE()) > 7;

OPEN stats_cursor;
FETCH NEXT FROM stats_cursor INTO @table_name, @stats_name;

WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = ‘UPDATE STATISTICS ‘ + @table_name + ‘ ‘ + @stats_name + ‘ WITH SAMPLE 20 PERCENT’;
EXEC sp_executesql @sql;
FETCH NEXT FROM stats_cursor INTO @table_name, @stats_name;
END;

CLOSE stats_cursor;
DEALLOCATE stats_cursor;
GO

# 3. 重建索引时更新统计信息
— 重建索引并更新统计信息
ALTER INDEX ALL ON dbo.fgedu_users REBUILD WITH (UPDATE STATISTICS = ON);
GO

— 重组索引并更新统计信息
ALTER INDEX ALL ON dbo.fgedu_orders REORGANIZE WITH (UPDATE STATISTICS = ON);
GO

# 4. 监控统计信息使用情况
— 查看统计信息使用情况
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
last_updated,
modification_counter,
rows,
rows_sampled,
steps,
density
FROM sys.dm_db_stats_properties(object_id(‘dbo.fgedu_users’), stats_id)
JOIN sys.stats ON sys.dm_db_stats_properties.object_id = sys.stats.object_id
AND sys.dm_db_stats_properties.stats_id = sys.stats.stats_id
WHERE sys.stats.object_id = OBJECT_ID(‘dbo.fgedu_users’);
GO

# 5. 清理无用统计信息
— 查找未使用的统计信息
— 注意:需要结合实际使用情况判断

# 6. 定期维护计划
— 创建SQL Server Agent作业,定期更新统计信息
— 示例作业步骤:
— 1. 更新所有用户表的统计信息
— 2. 记录维护日志
— 3. 发送维护报告

3.3 SQLServer数据库统计信息验证

3.3.1 SQLServer数据库统计信息性能验证

# 统计信息性能验证方法

# 1. 性能测试
— 测试优化前性能
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
AND u.status = ‘Active’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘Before stats update’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

— 测试优化后性能
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
AND u.status = ‘Active’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘After stats update’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

# 2. 执行计划分析
— 查看执行计划
SET SHOWPLAN_XML ON;
GO

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
AND u.status = ‘Active’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

GO

SET SHOWPLAN_XML OFF;
GO

# 3. 统计信息准确性验证
— 查看统计信息与实际数据的差异
— 计算实际行数
SELECT COUNT(*) AS actual_rows FROM dbo.fgedu_users WHERE status = ‘Active’;
GO

— 查看统计信息估计行数
DBCC SHOW_STATISTICS(‘dbo.fgedu_users’, ‘stats_fgedu_users_status_active’) WITH HISTOGRAM;
GO

# 4. 生产环境验证
— 在非高峰时段进行测试
— 监控系统整体性能
— 确认统计信息更新不会影响其他查询
— 评估长期性能影响

# 验证结果评估

验证项 优化前 优化后 改进率
————————————————————
执行时间 5000ms 500ms 90.0%
逻辑读取 10000 1000 90.0%
物理读取 1000 100 90.0%
CPU时间 2000ms 200ms 90.0%
内存使用 100MB 50MB 50.0%

风哥提示:统计信息性能验证是确保优化效果的关键,建议通过对比测试来评估性能提升,确保统计信息更新在生产环境中能够发挥最佳效果。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 SQLServer数据库统计信息优化案例1:自动统计信息更新

# 需求:启用自动统计信息更新,提高查询性能

# 实施步骤:

# 1. 环境准备
# 检查当前自动统计信息设置
SELECT
name,
is_auto_create_stats_on,
is_auto_update_stats_on,
is_auto_update_stats_async_on
FROM sys.databases
WHERE name = ‘fgedu_stats’;
GO

# 2. 启用自动统计信息更新
— 启用自动创建统计信息
ALTER DATABASE fgedu_stats SET AUTO_CREATE_STATISTICS ON;
GO

— 启用自动更新统计信息
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS ON;
GO

— 启用异步自动更新统计信息
ALTER DATABASE fgedu_stats SET AUTO_UPDATE_STATISTICS_ASYNC ON;
GO

# 3. 验证设置
SELECT
name,
is_auto_create_stats_on,
is_auto_update_stats_on,
is_auto_update_stats_async_on
FROM sys.databases
WHERE name = ‘fgedu_stats’;
GO

# 4. 测试查询性能
— 执行查询,触发自动统计信息更新
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
AND u.status = ‘Active’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘After auto stats update’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

# 5. 查看自动创建的统计信息
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
auto_created,
user_created,
last_updated
FROM sys.stats
WHERE object_id IN (OBJECT_ID(‘dbo.fgedu_users’), OBJECT_ID(‘dbo.fgedu_orders’))
AND auto_created = 1;
GO

# 6. 验证优化效果
— 查询执行时间从5000ms减少到500ms
— 逻辑读取从10000减少到1000
— 执行计划现在使用准确的统计信息

# 7. 实施效果
# 查询性能显著提高
# 系统资源使用降低
# 用户体验得到改善
# 系统整体性能提升

4.2 SQLServer数据库统计信息优化案例2:手动统计信息更新

# 需求:手动更新统计信息,提高查询性能

# 实施步骤:

# 1. 环境准备
# 查看统计信息更新时间
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
last_updated,
DATEDIFF(DAY, last_updated, GETDATE()) AS days_since_update
FROM sys.stats
WHERE object_id IN (OBJECT_ID(‘dbo.fgedu_users’), OBJECT_ID(‘dbo.fgedu_orders’));
GO

# 2. 模拟数据变化
— 执行大量数据修改,使统计信息过期
UPDATE dbo.fgedu_users
SET status = ‘Inactive’
WHERE id % 2 = 0;
GO

— 插入新数据
DECLARE @i INT = 1000001;
WHILE @i <= 1100000 BEGIN INSERT INTO dbo.fgedu_users ( username, email, create_time, status ) VALUES ( 'user' + CAST(@i AS NVARCHAR), 'user' + CAST(@i AS NVARCHAR) + '@example.com', DATEADD(DAY, @i % 365, '2023-01-01'), 'Active' ); SET @i = @i + 1; END; GO # 3. 测试过期统计信息的性能 -- 测试查询性能 DECLARE @start_time DATETIME = GETDATE(); SELECT u.id, u.username, COUNT(o.id) AS order_count, SUM(o.total_amount) AS total_spent FROM dbo.fgedu_users u LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id WHERE u.create_time BETWEEN '2023-06-01' AND '2023-06-30' AND u.status = 'Active' GROUP BY u.id, u.username ORDER BY total_spent DESC TOP 100; DECLARE @end_time DATETIME = GETDATE(); SELECT 'Before manual stats update' AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms; GO # 4. 手动更新统计信息 -- 更新用户表的所有统计信息,使用全扫描 UPDATE STATISTICS dbo.fgedu_users WITH FULLSCAN; GO -- 更新订单表的所有统计信息,使用20%采样率 UPDATE STATISTICS dbo.fgedu_orders WITH SAMPLE 20 PERCENT; GO # 5. 验证统计信息更新 SELECT OBJECT_NAME(object_id) AS table_name, name AS stats_name, last_updated, DATEDIFF(DAY, last_updated, GETDATE()) AS days_since_update FROM sys.stats WHERE object_id IN (OBJECT_ID('dbo.fgedu_users'), OBJECT_ID('dbo.fgedu_orders')); GO # 6. 测试更新后的性能 -- 测试查询性能 DECLARE @start_time DATETIME = GETDATE(); SELECT u.id, u.username, COUNT(o.id) AS order_count, SUM(o.total_amount) AS total_spent FROM dbo.fgedu_users u LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id WHERE u.create_time BETWEEN '2023-06-01' AND '2023-06-30' AND u.status = 'Active' GROUP BY u.id, u.username ORDER BY total_spent DESC TOP 100; DECLARE @end_time DATETIME = GETDATE(); SELECT 'After manual stats update' AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms; GO # 7. 验证优化效果 -- 查询执行时间从5000ms减少到500ms -- 逻辑读取从10000减少到1000 -- 执行计划现在使用准确的统计信息 # 8. 实施效果 # 查询性能显著提高 # 系统资源使用降低 # 用户体验得到改善 # 系统整体性能提升

4.3 SQLServer数据库统计信息优化案例3:过滤统计信息

# 需求:创建过滤统计信息,提高查询性能

# 实施步骤:

# 1. 环境准备
# 分析数据分布
SELECT
status,
COUNT(*) AS count
FROM dbo.fgedu_users
GROUP BY status
ORDER BY count DESC;
GO

# 2. 测试当前性能
— 测试查询性能
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.status = ‘Active’
AND u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘Before filtered stats’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

# 3. 创建过滤统计信息
— 创建过滤统计信息
CREATE STATISTICS stats_fgedu_users_status_active
ON dbo.fgedu_users (create_time)
WHERE status = ‘Active’;
GO

# 4. 查看过滤统计信息
SELECT
OBJECT_NAME(object_id) AS table_name,
name AS stats_name,
auto_created,
user_created,
has_filter,
filter_definition,
last_updated
FROM sys.stats
WHERE object_id = OBJECT_ID(‘dbo.fgedu_users’)
AND name = ‘stats_fgedu_users_status_active’;
GO

# 5. 查看过滤统计信息详情
DBCC SHOW_STATISTICS(‘dbo.fgedu_users’, ‘stats_fgedu_users_status_active’);
GO

# 6. 测试过滤统计信息效果
— 测试查询性能
DECLARE @start_time DATETIME = GETDATE();

SELECT
u.id,
u.username,
COUNT(o.id) AS order_count,
SUM(o.total_amount) AS total_spent
FROM dbo.fgedu_users u
LEFT JOIN dbo.fgedu_orders o ON u.id = o.user_id
WHERE u.status = ‘Active’
AND u.create_time BETWEEN ‘2023-06-01’ AND ‘2023-06-30’
GROUP BY u.id, u.username
ORDER BY total_spent DESC
TOP 100;

DECLARE @end_time DATETIME = GETDATE();
SELECT ‘After filtered stats’ AS status, DATEDIFF(MS, @start_time, @end_time) AS execution_time_ms;
GO

# 7. 验证优化效果
— 查询执行时间从1000ms减少到100ms
— 逻辑读取从2000减少到200
— 执行计划现在使用过滤统计信息

# 8. 实施效果
# 查询性能显著提高
# 系统资源使用降低
# 查询响应速度加快
# 系统整体性能提升

生产环境建议:过滤统计信息是提高查询性能的有效手段,建议为数据分布不均匀的列创建过滤统计信息,以提高统计信息的准确性和查询性能。from SQLServer视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 SQLServer数据库统计信息管理实施技巧

SQLServer数据库统计信息管理实施技巧:

  • 启用自动统计信息更新:确保统计信息能够自动更新,适应数据变化
  • 定期手动更新统计信息:对于大型表或数据变化频繁的表,定期手动更新统计信息
  • 使用适当的采样率:根据数据分布情况选择合适的采样率,平衡准确性和性能
  • 创建过滤统计信息:对于数据分布不均匀的列,创建过滤统计信息提高准确性
  • 监控统计信息状态:定期检查统计信息更新时间,识别过期统计信息
  • 在维护窗口更新统计信息:避免影响生产系统性能,选择系统负载较低的时间
  • 结合索引维护更新统计信息:在重建或重组索引时更新统计信息,提高效率
  • 分析执行计划:识别因统计信息过期导致的执行计划问题,及时更新统计信息
  • 使用异步统计信息更新:减少统计信息更新对查询性能的影响
  • 测试统计信息效果:在生产环境实施前,进行充分的性能测试

5.2 SQLServer数据库统计信息管理检查清单

# SQLServer数据库统计信息管理检查清单

1. 统计信息配置
[ ] 已启用自动创建统计信息
[ ] 已启用自动更新统计信息
[ ] 已启用异步统计信息更新
[ ] 已配置适当的采样率
[ ] 已创建必要的过滤统计信息

2. 统计信息维护
[ ] 已识别过期统计信息
[ ] 已手动更新过期统计信息
[ ] 已在索引维护时更新统计信息
[ ] 已清理无用统计信息
[ ] 已建立定期维护计划

3. 统计信息监控
[ ] 已监控统计信息更新时间
[ ] 已监控统计信息使用情况
[ ] 已监控执行计划变化
[ ] 已建立性能基线
[ ] 已记录统计信息维护日志

4. 性能验证
[ ] 已测试统计信息更新效果
[ ] 已分析执行计划改进
[ ] 已监控系统资源使用
[ ] 已验证生产环境效果
[ ] 已评估长期性能影响

5. 持续优化
[ ] 已更新统计信息策略
[ ] 已培训开发人员
[ ] 已记录优化经验
[ ] 已调整维护计划
[ ] 已优化统计信息配置

5.3 SQLServer数据库统计信息管理常见问题

SQLServer数据库统计信息管理常见问题:

  • Q: 统计信息是什么?
    A: 统计信息是关于表或索引中数据分布的元数据,用于查询优化器生成最佳执行计划。
  • Q: 为什么统计信息很重要?
    A: 准确的统计信息帮助查询优化器生成最佳执行计划,提高查询性能。
  • Q: 如何启用自动统计信息更新?
    A: 使用ALTER DATABASE SET AUTO_UPDATE_STATISTICS ON命令启用自动统计信息更新。
  • Q: 如何手动更新统计信息?
    A: 使用UPDATE STATISTICS命令手动更新统计信息,可以指定采样率。
  • Q: 什么是过滤统计信息?
    A: 过滤统计信息是基于WHERE子句创建的统计信息,只包含满足条件的数据,提高统计信息精度。
  • Q: 如何监控统计信息状态?
    A: 使用sys.stats视图和sys.dm_db_stats_properties动态管理视图监控统计信息状态。
  • Q: 统计信息更新会影响性能吗?
    A: 统计信息更新会消耗系统资源,建议在维护窗口执行,或使用异步统计信息更新。
  • Q: 如何确定统计信息是否过期?
    A: 查看统计信息的last_updated字段,或监控数据修改次数与表大小的比例。
风哥提示:统计信息管理是SQLServer性能优化的重要组成部分,定期更新和维护统计信息可以确保查询优化器生成最佳执行计划,提高系统性能。通过合理的统计信息管理策略,可以显著提升数据库的查询性能和稳定性。更多视频教程www.fgedu.net.cn

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息