SQL新手求助:已建索引仍无法提升百万级表查询性能
SQL查询性能优化建议(百万级数据场景)
嘿,作为SQL新手碰到百万级数据的性能瓶颈确实挺闹心的,尤其是已经加了索引还没起色的情况。先帮你拆解下当前的查询,再给你几个针对性的优化思路:
首先,先把你给出的查询结构整理完整(方便分析):
SELECT TOP 15 id, field1, field2 FROM ( SELECT DISTINCT 0 AS ID, tblsuites.suite Field1, 'Work Order' AS Field2 FROM tbljb_schedules INNER JOIN tblsuites ON tbljb_schedules.tblsuites_id = tblsuites.tblsuites_id ) AS subquery;
下面是具体的优化建议:
先确认
DISTINCT是否真的必要
你用DISTINCT大概率是因为tbljb_schedules和tblsuites是一对多关联,JOIN后产生了重复的suite值。但DISTINCT需要对结果集排序去重,百万级数据下这个开销很大。可以换成EXISTS来替代JOIN+DISTINCT,既能达到去重效果,又能避免不必要的JOIN操作:SELECT TOP 15 0 AS ID, s.suite Field1, 'Work Order' AS Field2 FROM tblsuites s WHERE EXISTS ( SELECT 1 FROM tbljb_schedules sch WHERE sch.tblsuites_id = s.tblsuites_id ) ORDER BY s.suite; -- 这里建议加排序,TOP15无排序的话结果是随机的检查索引是否真的“有用”
你说已经加了索引,但要确保是覆盖索引或者能被查询正确利用:- 对于
tbljb_schedules:建立以tblsuites_id为键的索引,因为查询只需要判断这个字段是否存在:CREATE NONCLUSTERED INDEX IX_tbljb_schedules_tblsuites_id ON tbljb_schedules(tblsuites_id); - 对于
tblsuites:如果查询只需要tblsuites_id和suite字段,建立覆盖索引(避免回表查询):CREATE NONCLUSTERED INDEX IX_tblsuites_id_suite ON tblsuites(tblsuites_id) INCLUDE (suite);
另外一定要查看执行计划(比如SQL Server里按Ctrl+L),看看有没有出现表扫描/索引扫描,如果有,要么是索引建错了,要么是统计信息过时。
- 对于
更新统计信息,帮优化器选对执行计划
百万级数据如果有大量插入/更新/删除,统计信息可能过时,导致查询优化器选择低效的执行计划。执行下面的语句更新统计信息:UPDATE STATISTICS tbljb_schedules; UPDATE STATISTICS tblsuites;去掉不必要的子查询
原查询套了一层子查询,但其实完全可以把TOP 15直接放到主查询里(用上面EXISTS的写法就不需要子查询了),减少查询的嵌套层级,让优化器更容易生成高效的执行计划。
内容的提问来源于stack exchange,提问作者Code Rider
相关产品推荐
相关产品推荐

