sqle icon indicating copy to clipboard operation
sqle copied to clipboard

规则:对联合索引左侧字段进行IN、OR等非等值查询会导致联合索引失效。误触发

Open winfredLIN opened this issue 1 year ago • 0 comments

版本信息(Version)

sqle 3.2410

问题描述(Describe)

SQL中的查询列分别是两个复合索引的首列,且其中一个不使用等值条件,会触发该问题

截图或日志(Log)

img_v3_02h7_62ce4da5-460c-4e84-a4d1-9e374604c60g

程序认为project id 在索引👉KEY ind_ATQ_CASE_03 (PROJECT_ID, FUNCTION_ID) 中,是第一个字段,但不是等值字段,所以触发了规则。 问题出在判断逻辑🚩标记的位置:

graph TD
    A[开始] --> B[过滤出多个字段的约束条件]
    B --> C[遍历所有多字段约束]
    C --> D[检查约束中的字段]
    D --> E{是否为最左字段🚩}
    E -->|是| F{是否使用等值查询🚩且未使用OR}
    F -->|是| G[符合规则]
    F -->|否| H[不符合规则, 返回 false🚩]
    E -->|否| I[继续检查下一个字段]
    G --> I
    I --> C
    C --> J{是否所有约束都符合规则}
    J -->|是| K[返回 true]
    J -->|否| L[返回 false]
    K --> M[结束]
    L --> M

如何复现(To Reproduce)

CREATE TABLE `case_table` (
  `CASE_ID` bigint(20) NOT NULL AUTO_INCREMENT  ,
  `PROJECT_ID` bigint(20) NOT NULL, 
  `FUNCTION_ID` bigint(20) DEFAULT NULL,
  `IS_DEL` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`CASE_ID`, `PROJECT_ID`) USING BTREE,
  KEY `ind_ATQ_CASE_01` (`IS_DEL`, `PROJECT_ID`),
  KEY `ind_ATQ_CASE_03` (`PROJECT_ID`, `FUNCTION_ID`)
) 

EXPLAIN SELECT COUNT(1)
FROM case_table
WHERE is_del = 0
  AND project_id IN (1, 2);

具体代码位置

if i == 0 && (!utils.StringsContains(colsWithEQ, col) || utils.StringsContains(colsWithOr, col)) {
	// 1.是最左字段 2.该字段没有使用等值查询或使用了or
	return false   // 👈break point

问题原因

解决方案

变更影响面

受影响的模块或功能

外部引用的潜在问题或风险

版本兼容性

测试建议

winfredLIN avatar Dec 03 '24 03:12 winfredLIN