MS SQL Server 2014含索引的LIKE查询耗时过长问题咨询
嘿,针对你这个SQL Server 2014上的查询慢问题,我给你梳理下核心原因和实际可行的优化方案:
首先,你的查询里LIKE '%criteria%'这种带前导通配符的写法,是性能瓶颈的头号元凶——SQL Server的索引是有序存储的,前导通配符没办法让数据库快速定位匹配行,只能被迫做全表扫描或者全索引扫描。再加上你Col_3上的非聚集索引还包含了查询不需要的列,索引体积变大,扫描起来更慢;最后DISTINCT关键字还会让数据库额外执行去重排序操作,又多了一层性能开销。
1. 把Col_3的索引改成覆盖索引
既然你的查询只用到了Col_1、Col_2、Col_3三列,那可以重建Col_3的非聚集索引,做成覆盖索引——只包含查询需要的列,这样即使做索引扫描,也不用回表去查额外数据,能大幅降低IO开销:
-- 先删除旧的Col_3非聚集索引(如果不需要的话) DROP INDEX IF EXISTS IX_Table_Col3_Old ON YourTableName; -- 创建覆盖索引 CREATE NONCLUSTERED INDEX IX_Table_Col3_Covering ON YourTableName (Col_3) INCLUDE (Col_1, Col_2);
2. 尽量避免前导通配符(业务允许的话)
如果你的业务场景可以接受只匹配后缀(比如LIKE 'criteria%'),那SQL Server就能直接利用Col_3的索引做范围查找,性能会瞬间提升一大截。但如果必须要前后都有通配符,那这个方法就用不了,得看下面的方案。
3. 用全文索引解决全模糊匹配
对于%xxx%这类全模糊匹配的场景,SQL Server的全文索引是专门优化这类查询的,比LIKE高效得多。操作步骤大概是:
- 给你的表创建一个全文目录
- 给Col_3列启用全文索引
- 把查询改成全文搜索的语法:
SELECT DISTINCT Col_1, Col_2, Col_3 FROM YourTableName WHERE CONTAINS(Col_3, 'criteria');
这个方法在11万行的表上,性能提升会非常明显。
4. 检查DISTINCT是否真的必要
先确认下:查询返回的(Col_1,Col_2,Col_3)组合是不是真的有重复?如果业务逻辑上这三列的组合本身就是唯一的,那DISTINCT完全可以去掉,省掉数据库的去重排序开销。
5. 查看执行计划定位精准瓶颈
建议你在SSMS里执行查询时,打开实际执行计划(快捷键Ctrl+M),看看数据库到底在做什么操作——比如是全表扫描还是索引扫描,有没有Key Lookup(回表)或者排序警告。执行计划能直观告诉你哪里拖慢了速度,比如看到Key Lookup就说明索引没覆盖全需要的列,这时候覆盖索引就刚好能解决问题。
SQL Server 2014虽然版本不算新,但上面的方案都是完全适配的。另外,你可以更新一下表的统计信息,确保查询优化器能生成最合理的执行计划:
UPDATE STATISTICS YourTableName;
内容的提问来源于stack exchange,提问作者Tiyyob

