先查PK列再取整行,还是首次直接查询整行的速度更快?
数据库两种查询方式的性能对比与方案价值
绝大多数常规场景下,第一次查询就直接获取所需完整行数据的方式速度更快。
原因很简单:先查主键再取整行的逻辑本质是两次独立的数据库请求,会额外多产生一次网络传输开销、查询解析开销、执行计划生成开销,拿到主键后再查整行的回表动作也没有比一次查询直接走索引回表少走步骤。如果是小数据量、查询条件能命中合适索引的普通查询,硬拆成两次请求纯属于增加无谓开销,性能肯定不如一次查完。
但先查PK再取整行的方案绝对不是毫无实际价值,反而在很多特定场景下是生产环境常用的性能优化手段,典型适用场景包括:
- 深分页优化:当需要查询的分页偏移量极大时(比如
LIMIT 100000, 10),直接查询整行会让数据库扫描并丢弃前10万条无关数据,IO和计算开销极高。此时可以先通过覆盖索引快速捞出符合筛选、排序条件的目标主键,再用主键匹配查询对应的整行数据,性能通常能提升数倍到数十倍,是解决深分页问题的主流方案。 - 复杂多表大查询拆分:当查询需要关联3张及以上的表、且涉及的字段多、筛选条件复杂时,直接JOIN查整行会生成体量极大的中间临时表,很容易把数据库内存、IO打满。这种场景下可以先根据强过滤条件捞出主表匹配的主键,按固定批次(比如每批200个ID)拆分后,再用主键关联其他表取完整数据,能把重查询拆成多个轻量查询,大幅降低数据库压力,提升查询稳定性。
- 冷热数据分层取数:如果业务做了冷热数据分离,比如热字段存在业务库、冷字段存在归档库或者对象存储,先查主键+热字段可以按需判断是否需要拉取冷数据,不需要冷字段的请求可以直接返回,避免每次查询都跨存储拉取全量整行的额外开销。
- 高并发锁冲突优化:在高并发更新场景下,如果直接查询整行加锁,会大幅拉长锁持有时间、提升锁冲突概率。可以先在快照读场景下快速捞出符合条件的主键,再分批根据主键加锁查询整行执行更新,能有效降低锁粒度、减少冲突,提升系统并发能力。
最后要注意,这个方案有明确的适用边界,普通小数据量的简单查询硬拆成两次请求,只会平白增加耗时,没必要强行套用。
内容的提问来源于stack exchange,提问作者alireza bodaghi
相关产品推荐
相关产品推荐

