Informix大表查询中FIRST 2比FIRST 1性能大幅下降的原因及FIRST机制咨询
Informix大表查询中FIRST 2比FIRST 1性能大幅下降的原因及FIRST机制咨询
嘿,我完全理解你遇到的这个困惑——面对一张超过1.26亿条记录的Informix大表,明明最终只返回1条结果,用FIRST 1查询时速度飞快,但换成FIRST 2就突然变得很慢,这确实有点反直觉。下面我结合你给出的执行计划,拆解下Informix中FIRST子句的工作逻辑,以及导致这种性能差异的原因:
一、Informix FIRST子句的核心工作机制
当你在查询中使用FIRST N时,数据库的核心目标是尽可能高效地获取前N条符合过滤条件的记录,但这里有个关键前提:优化器并不知道实际符合条件的记录数量,它会按照你指定的N值来规划执行路径,直到满足以下两个条件之一:
- 成功找到N条符合条件的记录;
- 遍历完所有可能包含符合条件记录的数据源,确认没有更多结果。
这意味着,当实际符合条件的记录数少于N时,数据库不会提前终止扫描,它会持续查找直到确定没有更多符合条件的行——这就是FIRST 2变慢的核心原因之一。
二、从你的执行计划看具体差异
对比两个查询的执行计划,能发现几个关键不同点:
FIRST 1的执行逻辑:
优化器选择了informix.tblpartition_indx_7索引,过滤条件为informix.financialt0_.id > 70201542。因为只需要1条记录,优化器会沿着这个索引快速扫描,一旦找到第一条符合条件的记录就立刻停止扫描,所以耗时极短,哪怕预估返回行数有434万+也不会影响实际执行速度。FIRST 2的执行逻辑:
优化器切换到了informix.itxnpartition_indx_7索引,虽然预估成本和FIRST 1接近,但这里的问题在于:- 优化器为了找到第二条记录,会持续扫描这个索引的所有分片(
fragments: ALL); - 由于实际只有1条符合条件的记录,它会遍历完索引中所有可能包含符合条件数据的部分,直到确认没有第二条记录存在,这个过程会消耗大量时间。
另外,索引的切换也是重要因素——itxnpartition_indx_7可能在扫描效率、数据分布上不如tblpartition_indx_7适合快速定位少量记录,进一步放大了性能差异。
- 优化器为了找到第二条记录,会持续扫描这个索引的所有分片(
三、针对这个问题的小建议
如果需要获取“所有符合条件的记录(最多2条)”,你可以尝试以下方法优化:
- 强制优化器使用
FIRST 1时的高效索引,比如通过SELECT FIRST 2 ... FROM ... USE INDEX (tblpartition_indx_7) ...的方式指定索引; - 更新表和索引的统计信息,让优化器更准确地判断符合条件的记录数量,从而选择更优的执行路径;
- 检查
itxnpartition_indx_7索引的设计,确认是否存在冗余或不合理的键值分布,导致扫描效率低下。
备注:内容来源于stack exchange,提问作者Saina Mohamadyari




