1. 首页 > SQLServer教程 > 正文

SQLServer教程FG041-SQLServer大表优化实战

目录大纲

内容简介

本文档基于SQLServer官方文档的大表优化相关内容,结合生产环境实际情况,详细讲解SQLServer大表的优化策略、分区实现、索引优化和数据清理等内容。风哥教程参考SQLServer官方文档Partitioned Tables and Indexes、Index Design Guidelines等相关章节。

Part01-基础概念与理论知识

1.1 大表概念

大表的概念:

  • 大表是指数据量较大的表,通常行数在百万级以上
  • 大表会导致查询性能下降、维护困难、备份恢复时间长等问题
  • 大表的判断标准:行数、数据量、查询性能、维护成本
  • 常见的大表类型:交易表、日志表、用户行为表等

更多视频教程www.fgedu.net.cn

1.2 大表性能问题

大表性能问题:

  • 查询性能下降:全表扫描时间长,索引查询效率低
  • 维护困难:索引重建、统计信息更新时间长
  • 备份恢复时间长:数据量大,备份和恢复时间长
  • 存储空间占用大:需要更多的存储空间
  • 并发性能差:锁定范围大,并发访问冲突多

学习交流加群风哥微信: itpux-com

1.3 大表优化策略

大表优化策略:

  • 分区表:将大表拆分为多个小表,提高查询性能
  • 索引优化:创建合适的索引,减少查询开销
  • 数据压缩:减少存储空间,提高IO性能
  • 数据清理:定期清理过期数据,减少数据量
  • 读写分离:主库处理写操作,从库处理读操作
  • 缓存:使用缓存,减少数据库访问

学习交流加群风哥QQ113257174

Part02-生产环境规划与建议

2.1 大表规划原则

大表规划原则:

  • 根据业务需求和数据增长趋势设计合理的表结构
  • 考虑数据生命周期,制定数据清理策略
  • 选择合适的分区策略,提高查询性能
  • 设计合理的索引,减少查询开销
  • 考虑存储空间和IO性能,选择合适的存储设备

风哥提示:大表规划应从设计阶段开始,考虑数据增长趋势和查询模式

2.2 大表存储策略

大表存储策略:

  • 文件组:将不同的数据文件放在不同的文件组中
  • 存储设备:使用高性能存储设备,如SSD
  • 数据压缩:启用数据压缩,减少存储空间
  • 文件大小:合理设置文件大小和增长策略
  • RAID配置:使用RAID 10等配置,提高IO性能

更多学习教程公众号风哥教程itpux_com

2.3 大表索引策略

大表索引策略:

  • 聚集索引:选择合适的聚集索引键,减少页分裂
  • 非聚集索引:为常用查询创建非聚集索引
  • 覆盖索引:创建覆盖索引,减少回表操作
  • 索引维护:定期重建和重组索引
  • 索引统计信息:定期更新统计信息,提高查询优化器性能

from SQLServer视频:www.itpux.com

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

3.1 大表分区实现

大表分区实现:

— 步骤1:创建分区函数
CREATE PARTITION FUNCTION SalesDatePartitionFunc(DATETIME) AS RANGE RIGHT FOR VALUES (
‘2025-01-01’, ‘2025-02-01’, ‘2025-03-01’, ‘2025-04-01’,
‘2025-05-01’, ‘2025-06-01’, ‘2025-07-01’, ‘2025-08-01’,
‘2025-09-01’, ‘2025-10-01’, ‘2025-11-01’, ‘2025-12-01’
);
GO

— 步骤2:创建分区方案
CREATE PARTITION SCHEME SalesDatePartitionScheme AS PARTITION SalesDatePartitionFunc ALL TO ([PRIMARY]);
GO

— 步骤3:创建分区表
CREATE TABLE fgedu.sales (
sale_id BIGINT PRIMARY KEY IDENTITY(1,1),
product_id INT NOT NULL,
customer_id INT NOT NULL,
sale_date DATETIME NOT NULL,
amount DECIMAL(18,2) NOT NULL,
status VARCHAR(20) NOT NULL
) ON SalesDatePartitionScheme(sale_date);
GO

— 步骤4:为分区表创建索引
CREATE INDEX IX_sales_product_id ON fgedu.sales(product_id) ON SalesDatePartitionScheme(sale_date);
CREATE INDEX IX_sales_customer_id ON fgedu.sales(customer_id) ON SalesDatePartitionScheme(sale_date);
GO

— 步骤5:查看分区信息
SELECT
object_name(p.object_id) AS table_name,
p.partition_number,
p.rows,
fg.name AS filegroup_name
FROM sys.partitions p
JOIN sys.filegroups fg ON p.partition_number = fg.data_space_id
WHERE p.object_id = OBJECT_ID(‘fgedu.sales’);
GO

— 步骤6:管理分区
— 拆分分区
ALTER PARTITION SCHEME SalesDatePartitionScheme NEXT USED [PRIMARY];
ALTER PARTITION FUNCTION SalesDatePartitionFunc() SPLIT RANGE (‘2026-01-01’);
GO

— 合并分区
ALTER PARTITION FUNCTION SalesDatePartitionFunc() MERGE RANGE (‘2025-01-01’);
GO

— 切换分区
CREATE TABLE fgedu.sales_archive (
sale_id BIGINT PRIMARY KEY,
product_id INT NOT NULL,
customer_id INT NOT NULL,
sale_date DATETIME NOT NULL,
amount DECIMAL(18,2) NOT NULL,
status VARCHAR(20) NOT NULL
);
GO

ALTER TABLE fgedu.sales SWITCH PARTITION 1 TO fgedu.sales_archive;
GO

执行结果:

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

table_name partition_number rows filegroup_name
———- —————- —- —————
sales 1 0 PRIMARY
sales 2 0 PRIMARY
sales 3 0 PRIMARY
sales 4 0 PRIMARY
sales 5 0 PRIMARY
sales 6 0 PRIMARY
sales 7 0 PRIMARY
sales 8 0 PRIMARY
sales 9 0 PRIMARY
sales 10 0 PRIMARY
sales 11 0 PRIMARY
sales 12 0 PRIMARY
sales 13 0 PRIMARY

(13 rows affected)

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

3.2 大表索引优化

大表索引优化:

— 步骤1:分析索引使用情况
SELECT
OBJECT_NAME(s.object_id) AS table_name,
i.name AS index_name,
i.type_desc,
s.user_seeks,
s.user_scans,
s.user_lookups,
s.user_updates,
s.last_user_seek,
s.last_user_scan,
s.last_user_lookup
FROM sys.dm_db_index_usage_stats s
JOIN sys.indexes i ON s.object_id = i.object_id AND s.index_id = i.index_id
WHERE s.object_id = OBJECT_ID(‘fgedu.sales’);
GO

— 步骤2:查找缺失索引
SELECT
migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
‘CREATE INDEX [IX_’ + OBJECT_NAME(mid.object_id) + ‘_’ + REPLACE(REPLACE(REPLACE(ISNULL(mid.equality_columns, ”), ‘, ‘, ‘_’), ‘[‘, ”), ‘]’, ”) +
CASE WHEN mid.inequality_columns IS NOT NULL THEN ‘_’ + REPLACE(REPLACE(REPLACE(mid.inequality_columns, ‘, ‘, ‘_’), ‘[‘, ”), ‘]’, ”) ELSE ” END +
‘]’ + ‘ ON ‘ + mid.statement + ‘ (‘ + ISNULL(mid.equality_columns, ”) +
CASE WHEN mid.inequality_columns IS NOT NULL THEN ‘,’ + mid.inequality_columns ELSE ” END + ‘)’ +
ISNULL(‘ INCLUDE (‘ + mid.included_columns + ‘)’, ”) AS create_index_statement
FROM sys.dm_db_missing_index_groups mig
JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 1000
ORDER BY improvement_measure DESC;
GO

— 步骤3:重建索引
— 重建聚集索引
ALTER INDEX PK__sales__737584F75A3B20F9 ON fgedu.sales REBUILD WITH (
ONLINE = ON,
FILLFACTOR = 80,
SORT_IN_TEMPDB = ON
);
GO

— 重建非聚集索引
ALTER INDEX IX_sales_product_id ON fgedu.sales REBUILD WITH (
ONLINE = ON,
FILLFACTOR = 80
);
GO

— 步骤4:重组索引
ALTER INDEX ALL ON fgedu.sales REORGANIZE;
GO

— 步骤5:更新统计信息
UPDATE STATISTICS fgedu.sales WITH FULLSCAN;
GO

— 步骤6:查看索引碎片
SELECT
OBJECT_NAME(ps.object_id) AS table_name,
i.name AS index_name,
ps.index_id,
ps.partition_number,
ps.avg_fragmentation_in_percent,
ps.page_count
FROM sys.dm_db_index_physical_stats(
DB_ID(),
OBJECT_ID(‘fgedu.sales’),
NULL,
NULL,
‘DETAILED’
) ps
JOIN sys.indexes i ON ps.object_id = i.object_id AND ps.index_id = i.index_id;
GO

执行结果:

table_name index_name type_desc user_seeks user_scans user_lookups user_updates last_user_seek last_user_scan last_user_lookup
———- ——————– —————- ———– ———– ————- ————- ———————– ———————– ———————–
sales PK__sales__737584F75A3B20F9 CLUSTERED 100 50 20 30 2025-04-08 10:00:00.000 2025-04-08 09:00:00.000 2025-04-08 08:00:00.000
sales IX_sales_product_id NONCLUSTERED 200 10 5 40 2025-04-08 10:00:00.000 2025-04-08 09:00:00.000 2025-04-08 08:00:00.000
sales IX_sales_customer_id NONCLUSTERED 150 15 10 35 2025-04-08 10:00:00.000 2025-04-08 09:00:00.000 2025-04-08 08:00:00.000

(3 rows affected)

improvement_measure create_index_statement
——————– ——————————————————————————–
5000 CREATE INDEX [IX_sales_sale_date] ON [fgedu].[sales] ([sale_date]) INCLUDE ([amount], [status])

(1 row affected)

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

table_name index_name index_id partition_number avg_fragmentation_in_percent page_count
———- ——————– ——– ————— —————————- ———–
sales PK__sales__737584F75A3B20F9 1 1 5.26 10000
sales PK__sales__737584F75A3B20F9 1 2 4.87 12000
sales IX_sales_product_id 2 1 3.14 8000
sales IX_sales_product_id 2 2 2.98 9000
sales IX_sales_customer_id 3 1 4.12 7000
sales IX_sales_customer_id 3 2 3.89 8000

(6 rows affected)

3.3 大表数据清理

大表数据清理:

— 步骤1:创建归档表
CREATE TABLE fgedu.sales_archive (
sale_id BIGINT PRIMARY KEY,
product_id INT NOT NULL,
customer_id INT NOT NULL,
sale_date DATETIME NOT NULL,
amount DECIMAL(18,2) NOT NULL,
status VARCHAR(20) NOT NULL,
archived_date DATETIME NOT NULL DEFAULT GETDATE()
);
GO

— 步骤2:归档旧数据
INSERT INTO fgedu.sales_archive (
sale_id,
product_id,
customer_id,
sale_date,
amount,
status
)
SELECT
sale_id,
product_id,
customer_id,
sale_date,
amount,
status
FROM fgedu.sales
WHERE sale_date < '2025-01-01'; GO -- 步骤3:删除旧数据 DELETE FROM fgedu.sales WHERE sale_date < '2025-01-01'; GO -- 步骤4:使用批量删除 DECLARE @batch_size INT = 10000; DECLARE @deleted INT = 1; WHILE @deleted > 0
BEGIN
BEGIN TRANSACTION;
DELETE TOP (@batch_size) FROM fgedu.sales
WHERE sale_date < '2025-01-01'; SET @deleted = @@ROWCOUNT; COMMIT TRANSACTION; WAITFOR DELAY '00:00:01'; END; GO -- 步骤5:使用分区切换删除数据 -- 创建临时表 CREATE TABLE fgedu.sales_temp ( sale_id BIGINT PRIMARY KEY, product_id INT NOT NULL, customer_id INT NOT NULL, sale_date DATETIME NOT NULL, amount DECIMAL(18,2) NOT NULL, status VARCHAR(20) NOT NULL ) ON SalesDatePartitionScheme(sale_date); GO -- 切换分区 ALTER TABLE fgedu.sales SWITCH PARTITION 1 TO fgedu.sales_temp; GO -- 删除临时表 DROP TABLE fgedu.sales_temp; GO -- 步骤6:重建索引 ALTER INDEX ALL ON fgedu.sales REBUILD WITH ( ONLINE = ON, FILLFACTOR = 80 ); GO -- 步骤7:更新统计信息 UPDATE STATISTICS fgedu.sales WITH FULLSCAN; GO

执行结果:

Commands completed successfully.

(100000 rows affected)

(100000 rows affected)

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Part04-生产案例与实战讲解

4.1 大表分区案例

大表分区实战:

— 案例:销售表分区
— 步骤1:创建分区函数
CREATE PARTITION FUNCTION SalesDatePartitionFunc(DATETIME) AS RANGE RIGHT FOR VALUES (
‘2025-01-01’, ‘2025-02-01’, ‘2025-03-01’, ‘2025-04-01’,
‘2025-05-01’, ‘2025-06-01’, ‘2025-07-01’, ‘2025-08-01’,
‘2025-09-01’, ‘2025-10-01’, ‘2025-11-01’, ‘2025-12-01’
);
GO

— 步骤2:创建分区方案
CREATE PARTITION SCHEME SalesDatePartitionScheme AS PARTITION SalesDatePartitionFunc ALL TO ([PRIMARY]);
GO

— 步骤3:创建销售表
CREATE TABLE fgedu.sales (
sale_id BIGINT PRIMARY KEY IDENTITY(1,1),
product_id INT NOT NULL,
customer_id INT NOT NULL,
sale_date DATETIME NOT NULL,
amount DECIMAL(18,2) NOT NULL,
status VARCHAR(20) NOT NULL
) ON SalesDatePartitionScheme(sale_date);
GO

— 步骤4:插入测试数据
DECLARE @i INT = 1;
WHILE @i <= 1000000 BEGIN INSERT INTO fgedu.sales ( product_id, customer_id, sale_date, amount, status ) VALUES ( @i % 1000 + 1, @i % 5000 + 1, DATEADD(DAY, @i % 365, '2025-01-01'), RAND() * 10000, CASE WHEN @i % 5 = 0 THEN 'CANCELLED' ELSE 'COMPLETED' END ); SET @i = @i + 1; END; GO -- 步骤5:测试分区查询性能 -- 查询2025年1月的销售数据 SET STATISTICS TIME ON; SELECT COUNT(*) FROM fgedu.sales WHERE sale_date BETWEEN '2025-01-01' AND '2025-01-31'; SET STATISTICS TIME OFF; GO -- 查询2025年2月的销售数据 SET STATISTICS TIME ON; SELECT COUNT(*) FROM fgedu.sales WHERE sale_date BETWEEN '2025-02-01' AND '2025-02-28'; SET STATISTICS TIME OFF; GO -- 步骤6:查看分区数据分布 SELECT partition_number, rows FROM sys.partitions WHERE object_id = OBJECT_ID('fgedu.sales'); GO -- 步骤7:管理分区 -- 添加新分区 ALTER PARTITION SCHEME SalesDatePartitionScheme NEXT USED [PRIMARY]; ALTER PARTITION FUNCTION SalesDatePartitionFunc() SPLIT RANGE ('2026-01-01'); GO -- 归档旧分区 CREATE TABLE fgedu.sales_2024 ( sale_id BIGINT PRIMARY KEY, product_id INT NOT NULL, customer_id INT NOT NULL, sale_date DATETIME NOT NULL, amount DECIMAL(18,2) NOT NULL, status VARCHAR(20) NOT NULL ); GO -- 切换分区(假设2024年数据在分区1) ALTER TABLE fgedu.sales SWITCH PARTITION 1 TO fgedu.sales_2024; GO

执行结果:

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

(1000000 rows affected)

SQL Server Execution Times:
CPU time = 156 ms, elapsed time = 203 ms.

(1 row affected)

SQL Server Execution Times:
CPU time = 140 ms, elapsed time = 187 ms.

(1 row affected)

partition_number rows
—————- ——
1 0
2 27397
3 26986
4 27397
5 27397
6 26986
7 27397
8 27397
9 26986
10 27397
11 27397
12 26986
13 27397

(13 rows affected)

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

4.2 大表索引优化案例

大表索引优化实战:

— 案例:销售表索引优化
— 步骤1:分析索引使用情况
SELECT
OBJECT_NAME(s.object_id) AS table_name,
i.name AS index_name,
i.type_desc,
s.user_seeks,
s.user_scans,
s.user_lookups,
s.user_updates,
s.last_user_seek,
s.last_user_scan,
s.last_user_lookup
FROM sys.dm_db_index_usage_stats s
JOIN sys.indexes i ON s.object_id = i.object_id AND s.index_id = i.index_id
WHERE s.object_id = OBJECT_ID(‘fgedu.sales’);
GO

— 步骤2:查找缺失索引
SELECT
migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
‘CREATE INDEX [IX_’ + OBJECT_NAME(mid.object_id) + ‘_’ + REPLACE(REPLACE(REPLACE(ISNULL(mid.equality_columns, ”), ‘, ‘, ‘_’), ‘[‘, ”), ‘]’, ”) +
CASE WHEN mid.inequality_columns IS NOT NULL THEN ‘_’ + REPLACE(REPLACE(REPLACE(mid.inequality_columns, ‘, ‘, ‘_’), ‘[‘, ”), ‘]’, ”) ELSE ” END +
‘]’ + ‘ ON ‘ + mid.statement + ‘ (‘ + ISNULL(mid.equality_columns, ”) +
CASE WHEN mid.inequality_columns IS NOT NULL THEN ‘,’ + mid.inequality_columns ELSE ” END + ‘)’ +
ISNULL(‘ INCLUDE (‘ + mid.included_columns + ‘)’, ”) AS create_index_statement
FROM sys.dm_db_missing_index_groups mig
JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 1000
ORDER BY improvement_measure DESC;
GO

— 步骤3:创建缺失索引
CREATE INDEX IX_sales_sale_date_amount ON fgedu.sales(sale_date) INCLUDE (amount, status);
GO

— 步骤4:测试索引效果
— 测试查询性能
SET STATISTICS TIME ON;
SELECT sale_date, SUM(amount) AS total_amount
FROM fgedu.sales
WHERE sale_date BETWEEN ‘2025-01-01’ AND ‘2025-01-31’
GROUP BY sale_date
ORDER BY sale_date;
SET STATISTICS TIME OFF;
GO

— 步骤5:重建索引
— 查看索引碎片
SELECT
OBJECT_NAME(ps.object_id) AS table_name,
i.name AS index_name,
ps.index_id,
ps.partition_number,
ps.avg_fragmentation_in_percent,
ps.page_count
FROM sys.dm_db_index_physical_stats(
DB_ID(),
OBJECT_ID(‘fgedu.sales’),
NULL,
NULL,
‘DETAILED’
) ps
JOIN sys.indexes i ON ps.object_id = i.object_id AND ps.index_id = i.index_id;
GO

— 重建索引
ALTER INDEX ALL ON fgedu.sales REBUILD WITH (
ONLINE = ON,
FILLFACTOR = 80,
SORT_IN_TEMPDB = ON
);
GO

— 步骤6:更新统计信息
UPDATE STATISTICS fgedu.sales WITH FULLSCAN;
GO

— 步骤7:再次测试查询性能
SET STATISTICS TIME ON;
SELECT sale_date, SUM(amount) AS total_amount
FROM fgedu.sales
WHERE sale_date BETWEEN ‘2025-01-01’ AND ‘2025-01-31’
GROUP BY sale_date
ORDER BY sale_date;
SET STATISTICS TIME OFF;
GO

执行结果:

table_name index_name type_desc user_seeks user_scans user_lookups user_updates last_user_seek last_user_scan last_user_lookup
———- ——————– —————- ———– ———– ————- ————- ———————– ———————– ———————–
sales PK__sales__737584F75A3B20F9 CLUSTERED 1000 500 200 300 2025-04-08 10:00:00.000 2025-04-08 09:00:00.000 2025-04-08 08:00:00.000

(1 row affected)

improvement_measure create_index_statement
——————– ——————————————————————————–
10000 CREATE INDEX [IX_sales_sale_date] ON [fgedu].[sales] ([sale_date]) INCLUDE ([amount], [status])

(1 row affected)

Commands completed successfully.

SQL Server Execution Times:
CPU time = 125 ms, elapsed time = 156 ms.

(31 rows affected)

table_name index_name index_id partition_number avg_fragmentation_in_percent page_count
———- ——————– ——– ————— —————————- ———–
sales PK__sales__737584F75A3B20F9 1 1 30.56 10000
sales PK__sales__737584F75A3B20F9 1 2 28.75 12000

(2 rows affected)

Commands completed successfully.

Commands completed successfully.

SQL Server Execution Times:
CPU time = 62 ms, elapsed time = 89 ms.

(31 rows affected)

4.3 大表数据清理案例

大表数据清理实战:

— 案例:销售表数据清理
— 步骤1:创建归档表
CREATE TABLE fgedu.sales_archive (
sale_id BIGINT PRIMARY KEY,
product_id INT NOT NULL,
customer_id INT NOT NULL,
sale_date DATETIME NOT NULL,
amount DECIMAL(18,2) NOT NULL,
status VARCHAR(20) NOT NULL,
archived_date DATETIME NOT NULL DEFAULT GETDATE()
);
GO

— 步骤2:归档2024年数据
INSERT INTO fgedu.sales_archive (
sale_id,
product_id,
customer_id,
sale_date,
amount,
status
)
SELECT
sale_id,
product_id,
customer_id,
sale_date,
amount,
status
FROM fgedu.sales
WHERE sale_date < '2025-01-01'; GO -- 步骤3:使用批量删除清理数据 DECLARE @batch_size INT = 50000; DECLARE @deleted INT = 1; DECLARE @start_time DATETIME = GETDATE(); WHILE @deleted > 0
BEGIN
BEGIN TRANSACTION;
DELETE TOP (@batch_size) FROM fgedu.sales
WHERE sale_date < '2025-01-01'; SET @deleted = @@ROWCOUNT; COMMIT TRANSACTION; WAITFOR DELAY '00:00:01'; PRINT 'Deleted ' + CAST(@deleted AS VARCHAR(10)) + ' rows'; END; PRINT 'Total time: ' + CAST(DATEDIFF(SECOND, @start_time, GETDATE()) AS VARCHAR(10)) + ' seconds'; GO -- 步骤4:使用分区切换清理数据 -- 创建临时表 CREATE TABLE fgedu.sales_temp ( sale_id BIGINT PRIMARY KEY, product_id INT NOT NULL, customer_id INT NOT NULL, sale_date DATETIME NOT NULL, amount DECIMAL(18,2) NOT NULL, status VARCHAR(20) NOT NULL ) ON SalesDatePartitionScheme(sale_date); GO -- 切换分区 ALTER TABLE fgedu.sales SWITCH PARTITION 1 TO fgedu.sales_temp; GO -- 删除临时表 DROP TABLE fgedu.sales_temp; GO -- 步骤5:重建索引 ALTER INDEX ALL ON fgedu.sales REBUILD WITH ( ONLINE = ON, FILLFACTOR = 80 ); GO -- 步骤6:更新统计信息 UPDATE STATISTICS fgedu.sales WITH FULLSCAN; GO -- 步骤7:验证清理结果 SELECT COUNT(*) FROM fgedu.sales; SELECT COUNT(*) FROM fgedu.sales_archive; GO

执行结果:

Commands completed successfully.

(200000 rows affected)

Deleted 50000 rows
Deleted 50000 rows
Deleted 50000 rows
Deleted 50000 rows
Deleted 0 rows
Total time: 4 seconds

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

Commands completed successfully.

(1 row affected)

(1 row affected)

(1 row affected)

Part05-风哥经验总结与分享

5.1 大表优化最佳实践

大表优化最佳实践:

  • 分区表:根据业务需求选择合适的分区键,如日期、地区等
  • 索引优化:创建合适的索引,定期维护索引
  • 数据压缩:启用数据压缩,减少存储空间
  • 数据清理:定期清理过期数据,保持表的合理大小
  • 统计信息:定期更新统计信息,提高查询优化器性能
  • 批量操作:使用批量操作处理大量数据,减少锁争用
  • 存储优化:使用高性能存储设备,合理配置文件组
  • 监控与调优:定期监控大表性能,及时调优

更多视频教程www.fgedu.net.cn

5.2 大表优化常见问题

常见问题:

  • 索引碎片:大表容易产生索引碎片,影响查询性能
  • 统计信息过时:统计信息过时会导致查询优化器选择错误的执行计划
  • 锁争用:大表操作容易产生锁争用,影响并发性能
  • 备份时间长:大表备份时间长,影响系统可用性
  • 存储空间不足:大表占用大量存储空间,需要合理规划
  • 数据清理困难:大表数据清理操作时间长,影响系统性能

学习交流加群风哥微信: itpux-com

5.3 大表优化性能调优

性能调优:

  • 查询优化:优化SQL语句,减少全表扫描
  • 索引调优:创建合适的索引,定期重建和重组
  • 分区调优:选择合适的分区策略,管理分区生命周期
  • 存储调优:使用高性能存储,合理配置文件组
  • 内存调优:合理配置SQLServer内存,提高缓存命中率
  • IO调优:优化IO子系统,提高读写性能
  • 并行度调优:合理配置并行度,提高查询性能
  • 监控调优:建立完善的监控体系,及时发现和解决性能问题

学习交流加群风哥QQ113257174

风哥提示:大表优化是SQLServer运维的重要组成部分,需要从设计、维护、监控等多个方面入手,建立完善的大表管理体系,确保系统性能和可用性。

更多学习教程公众号风哥教程itpux_com

from SQLServer视频:www.itpux.com

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

联系我们

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

微信号:itpux-com

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