SqlServer查询性能影响因素:
 索引不足或不准确
 统计不准确
 查询设计不当
 频繁阻塞和死锁
 索引碎片过多

索引不足或不准确

简单缺少索引问题,可以通过使用查询计划进行分析,直接使用它的产生的脚本
image-1716982632953

复杂的情况,需要结合性能指标、硬件资源与业务逻辑进行综合评估,然后在这三者之间取舍。性能指标可以在性能计数器与DM管理视图表中收集
image-1716982979707

统计不准确

查询stats表,通过更新日期(Updated)、修改的行数(Rows Sampled/Rows)、修改的行数百分比(Modification Counter)关键指标来决定是否要需要手动执行统计更新
image-1716984293591

当然也可以全库查询。

SELECT ut.name AS Table_name,  ss.name as IndexName, STATS_DATE(ut.id, stats_id) AS statistics_update_date
FROM sys.stats ss,  sysobjects ut where ut.xtype='U'  and ss.object_id=ut.id 
and STATS_DATE(ut.id, stats_id) is not null
order by statistics_update_date desc

查询设计不当

可能根据查询执行顺序,来了解大致的查询过程需要的集合大小,与运算符运复杂度。
image-1716983214558

  1. 通过常规问题回避。
  2. 通过查询优化顾问给出的建议,进行调整。。
  3. 不断地调整SQL输入输出的集合与运算量,对比每次调整的查询计划,进行迭代优化。

频繁阻塞和死锁

参考前面了解SqlServer阻塞
了解sqlserver死锁

索引碎片过多

在 SQL Server 中,索引碎片(fragmentation)会影响查询性能。当索引的碎片率较高时,适合进行索引重建(rebuild)或重组(reorganize)操作。具体来说,可以使用 sys.dm_db_index_physical_stats 动态管理视图来检查索引的碎片率,并根据以下指导原则决定是否需要重建或重组索引。

碎片率阈值
根据经验,通常的索引维护策略如下:

  • 碎片率低于 10%:通常不需要进行任何操作。
  • 碎片率在 10% 到 30% 之间:适合进行索引重组(reorganize)。
  • 碎片率超过 30%:适合进行索引重建(rebuild)。

查询索引碎片率

SELECT 
    dbschemas.[name] AS 'Schema',
    dbtables.[name] AS 'Table',
    dbindexes.[name] AS 'Index',
    indexstats.avg_fragmentation_in_percent
FROM 
    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') AS indexstats
    INNER JOIN sys.tables AS dbtables ON indexstats.object_id = dbtables.object_id
    INNER JOIN sys.schemas AS dbschemas ON dbtables.schema_id = dbschemas.schema_id
    INNER JOIN sys.indexes AS dbindexes ON indexstats.object_id = dbindexes.object_id
        AND indexstats.index_id = dbindexes.index_id
WHERE 
    indexstats.database_id = DB_ID()
ORDER BY 
    indexstats.avg_fragmentation_in_percent DESC;