SQL Server查询1700万条记录表耗时10分钟,查询缓慢原因是什么?
查询运行缓慢的核心原因
- 索引覆盖性不足:你创建的
GatewayChannelId单列非聚集索引仅存储了该字段与主键Id值,而查询使用select *要求返回表中所有字段,此时数据库有两种执行路径:要么走GatewayChannelId索引查找,再通过主键Id回聚集索引查询剩余所有字段(键查找);要么直接放弃索引执行全表聚集索引扫描。 - 索引筛选性差触发全表扫描:如果
gatewaychannelId in (1,2,3)命中的记录占1700万总数据的比例超过10%~20%,数据库优化器会判定走索引+回表的随机IO开销远高于顺序读全表的开销,最终选择全表扫描,导致耗时极长。 - 回表开销过大:即便命中记录占比不高走了索引查找,每次匹配到符合条件的记录都要执行一次回表操作,命中的记录数越多,累计的随机IO开销越大,执行效率会线性下降。
可选优化方案
- 避免使用
select *,仅指定实际需要返回的字段,再针对查询创建覆盖索引:比如查询需要返回Id、CustomerId、Price、EntryDate四个字段,可以创建索引CREATE INDEX IX_GatewayReceipt_GatewayChannelId ON bas.GatewayReceipt(GatewayChannelId) INCLUDE (CustomerId,Price,EntryDate),直接通过索引就能拿到所有需要的字段,无需回表。 - 如果查询结果量级很大需要分页,搭配
OFFSET FETCH或分页逻辑拆分查询,避免一次性加载全量结果。 - 若1、2、3三个渠道的记录占比确实极高,可以考虑按
GatewayChannelId做表分区,减少扫描的数据范围。
内容的提问来源于stack exchange,提问作者Ehsan Akbar
相关产品推荐
相关产品推荐

