SQL UPDATE, WHERE 条件限制(索引停止工作)

Posted

技术标签:

【中文标题】SQL UPDATE, WHERE 条件限制(索引停止工作)【英文标题】:SQL UPDATE, WHERE conditions limitation (index stop work) 【发布时间】:2019-12-06 20:18:51 【问题描述】:

如果我有多个 OR 对,例如 ((ID = 5 AND TEST_DATE = '2019-01-17 05:56:19.0')),索引将停止工作

SQL Where 子句有限制吗? SQL 优化器决定使用全扫描? 数据库查询设置限制?

我可以将 sql 拆分成小块。

EXPLAIN
      UPDATE TEST_TABLE
      SET MY_FLAG=1
      WHERE (ID = 1 AND TEST_DATE = '2019-01-15 01:24:01.0') ||
            (ID = 2 AND TEST_DATE = '2019-01-15 02:14:02.0') ||
            (ID = 3 AND TEST_DATE = '2019-01-16 03:32:08.0') ||
            (ID = 4 AND TEST_DATE = '2019-01-16 04:45:19.0') ||
            (ID = 5 AND TEST_DATE = '2019-01-17 05:56:19.0')

解释结果1:OR 对 > 200

(1, 'SIMPLE', 'TEST_TABLE', 'range', 'PRIMARY,test_date_index', 'PRIMARY', '8', NULL, 316, 'Using where');

解释结果2:OR 对 > 300

(1, 'SIMPLE', 'TEST_TABLE', 'index', NULL, 'PRIMARY', '8', NULL, 51425278, 'Using where');

表结构:

CREATE TABLE `TEST_TABLE` (
    `ID` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `ATTR_ADDRESS` VARCHAR(255) NULL DEFAULT NULL,
    `ATTR_CITY` VARCHAR(40) NULL DEFAULT NULL,
    `ATTR_COUNTRY` VARCHAR(40) NULL DEFAULT NULL,
    `TEST_DATE` DATETIME NOT NULL,
    `MY_FLAG` BIT(1) NOT NULL DEFAULT b'0',
    PRIMARY KEY (`ID`),
    INDEX `test_date_index` (`TEST_DATE`),
    INDEX `MY_FLAG` (`MY_FLAG`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

【问题讨论】:

你在 (id,test_date) 上有一个索引? 是的主要 id 和次要 test_date_index。 表是 InnoDB 吗? 是的,InnoDB。当前数据库是 MariaDB 10.0.x。 在这种情况下,我在这里看不到任何进一步的优化范围 - 但希望其他人能够提出一些建议。 【参考方案1】:

优化器没有足够的信息来决定哪种方式更适合执行查询。如果你发现,比如说,200 是“更快”执行的安全限制,那么就将它分块。也就是说,一次只执行 200 行。

或者,您可以尝试将 ID、日期对放在另一个表中,然后执行“多表 UPDATE”。它可能运行得更快。在test_table 中包含“复合”INDEX(test_date, id)

【讨论】:

以上是关于SQL UPDATE, WHERE 条件限制(索引停止工作)的主要内容,如果未能解决你的问题,请参考以下文章

SQL注入 | 二次注入

SQL语句update中的where条件的用法问题

MySQL 调优 —— Using filesort

SQL入门-DML数据操作语言

SQL指令问题,怎么update第一排的数据,没有where条件。

sql update和insert效率