You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

千万级数据表两类查询性能对比咨询:无索引单字段VS带索引组合条件

关于两种查询场景的性能分析

你的判断大部分情况下是正确的,但我们得结合数据库的执行逻辑和几个关键细节来更精准地分析:

为什么场景2通常更快?

场景1的SQL select * from table where product_id = 123456 因为product_id没有索引,数据库只能执行全表扫描(Full Table Scan)——也就是逐行遍历1000万条记录,逐一比对product_id的值,这个过程的IO和CPU开销极大,速度会非常慢。

而场景2的SQL select * from table where shopname ='abz' and product_id = 123456shopname带有索引,数据库会先通过索引快速定位到所有shopname='abz'的记录:

  • 这个过程是索引查找(Index Seek),只需要遍历索引树就能定位目标数据,不需要扫全表;
  • 之后再在这个小得多的结果集里筛选product_id=123456的记录,哪怕product_id没索引,小范围的遍历开销也远低于全表扫描。

需要注意的例外情况

不过有两种场景下,场景2的性能优势可能会打折扣甚至消失:

  • shopname='abz'的结果集过大时:如果这个条件返回的记录占全表的30%以上(不同数据库的阈值略有差异),数据库优化器可能会认为“用索引查找后再回表的开销”比直接全表扫描更高,从而选择放弃使用shopname索引,这时候场景2的执行逻辑就和场景1差不多了。
  • 索引类型的影响:如果shopname是单独的单列索引,数据库找到匹配的记录后需要通过主键回表获取product_id和其他字段(也就是书签查找/Key Lookup);但如果是(shopname, product_id)的复合索引,数据库可以直接从索引中拿到需要的筛选条件,甚至如果复合索引包含所有查询字段(覆盖索引),连回表都不需要,性能会比单列索引更优。

总结

在绝大多数正常业务场景下(shopname='abz'的结果集较小),场景2的查询速度会远快于场景1;只有当shopname的筛选结果集异常庞大时,两者的性能才可能接近。

内容的提问来源于stack exchange,提问作者Joumana Issa

火山引擎 最新活动