更新时间:2024-09-06 GMT+08:00

功能介绍

GaussDB(for MySQL)支持IN谓词转子查询功能。对于满足如下条件的复杂查询,通过该功能优化器可以将某些大的IN谓词转换为IN子查询,从而提升复杂查询的执行性能。

  • GaussDB(for MySQL)内核版本为2.0.42.230600或以上的版本。
  • IN列表中的元素个数超过rds_in_predicate_conversion_threshold参数设置的个数。

概述

社区MySQL在处理column IN (const1, const2, .... )时,如果column上面有索引,那么通常优化器会选择Range scan进行扫描。但是在进行Range scan分析的时候,range_optimizer_max_mem_size定义了分析过程中需要的最大内存。如果IN后面的list非常大,使用的内存会超过定义的最大内存,会使得Range scan失效,从而引发查询的性能下降。如果想解决该问题,可以调大允许使用的最大内存,但是该内存是session级别的,也就是说每个session进行该查询都会占用同样的内存,所以容易引发用户实例发生OOM。另外即使可以做range optimizer,如果in value过多超过eq_range_index_dive_limit限制,导致无法走index dive而只能走索引统计信息,而大量value所对应的统计信息比较简单,很有可能出现估算不准确的情况,导致性能回退。将IN子句转换为子查询,转换为subquery之后,后续优化器会继续考虑是否转换为semijoin,提升性能。具体变换过程如下:

select ... from lineitem where l_partkey in (...)

====>

select ... from lineitem where l_partkey in 
 (select tb._col_1 from (values (9628136),(19958441),...) tb)