注册

WHERE 子句中多列 IN 谓词导致优化器索引失效及查询性能严重下降

赖锦辉 2026/07/25 452 1

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:DM 8.1
【操作系统】:Ubuntu 22.04
【CPU】:
【问题描述】*:WHERE子句包含多列组合IN谓词(行值构造器)时,优化器未能利用主键索引,执行计划严重偏离预期,导致查询响应时间从毫秒级劣化至秒级。

两条查询语义完全等价,但性能相差约 1635 倍。

CREATE TABLE t0 (c0 INT PRIMARY KEY); CREATE TABLE t1 (c0 INT PRIMARY KEY); INSERT INTO t0 SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 1000000; INSERT INTO t1 SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 1000; SELECT * FROM t0, t1 WHERE (t0.c0, t1.c0) IN ((0,0),(1,1)); -- 实际执行耗时:约 7.4 秒 SELECT * FROM t0, t1 WHERE (t0.c0 = 0 AND t1.c0 = 0) OR (t0.c0 = 1 AND t1.c0 = 1); -- 实际执行耗时:4.527 毫秒

查询计划分析:

  • 优化器将常量值列表 (0,0),(1,1) 作为哈希连接的构建侧,而将 t1 与 t0 的全索引扫描(SSCN)结果作为探测侧。
  • 实际执行时,t1(1000 行)与 t0(100 万行)先进行了笛卡尔积式的嵌套循环连接,中间结果规模高达 10 亿次比较,随后才通过哈希半连接进行过滤。
  • 两个主键索引仅被用于全表扫描,完全未发挥点查的索引优势。
1   #NSET2: [19801482, 50000000, 8] 
2     #PRJT2: [19801482, 50000000, 8]; exp_num(2), is_atom(FALSE) 
3       #HASH RIGHT SEMI JOIN2: [19801482, 50000000, 8]; n_keys(2) 
         KEY(DMTEMPVIEW_889193482.colname=T0.C0 AND DMTEMPVIEW_889193482.colname=T1.C0) 
         KEY_NULL_EQU(0, 0)
4         #CONST VALUE LIST: [1, 2, 8]; row_num(2), col_num(2)
5         #NEST LOOP INNER JOIN2: [19801482, 50000000, 8] 
6           #SSCN: [1, 1000, 4]; INDEX33555474(T1); btr_scan(1); is_global(0)
7           #SSCN: [105, 1000000, 4]; INDEX33555472(T0); btr_scan(1); is_global(0)

预期执行计划:优化器应识别多列 IN 谓词与 OR 展开的等价性,将条件直接下推至基表扫描阶段,分别通过主键索引定位 (0,0) 和 (1,1) 两行数据,时间复杂度应为常数级。

回答 0
暂无回答
扫一扫
联系客服