【问题标题】:MySQL update not support index condition pushdown?MySQL 更新不支持索引条件下推?
【发布时间】:2021-02-26 03:28:01
【问题描述】:
CREATE TABLE `t2` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  `c` char(10) DEFAULT NULL,
  `d` varchar(256) DEFAULT NULL,
  `e` text,
  KEY `ii1` (`a`,`b`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

sql1: update t2 set b = 3 where a = 1;
sql2: select b from t2 where a = 1;

sql2会使用索引条件下推,而sql1不会,但是为什么,引擎和服务器之间转换的数据格式是这样的?

mysql> explain select b from t2 where a = 1;
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t2    | NULL       | ref  | ii1           | ii1  | 5       | const |    1 |   100.00 | Using index |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain update t2 set b = 3 where a = 1;
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref   | rows | filtered | Extra                        |
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+------------------------------+
|  1 | UPDATE      | t2    | NULL       | range | ii1           | ii1  | 5       | const |    1 |   100.00 | Using where; Using temporary |
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+------------------------------+
1 row in set (0.00 sec)

【问题讨论】:

    标签: mysql mariadb innodb


    【解决方案1】:

    注释Using index 表示查询正在使用覆盖索引。这意味着 SELECT 查询可以通过仅读取索引来返回结果。这对于 INSERT/UPDATE/DELETE 是不可能的,因为索引和索引所属的表必须同时更新。

    注释Using index condition 用于索引条件下推。这是将一些预过滤委托给存储引擎的功能。

    EXPLAIN 输出中的单词相似,但这两个注释指的是完全不同的特征。

    【讨论】:

    • 谢谢比尔,但我仍然想知道为什么 UPDATE 会在执行更新之前检索整个记录? IE。 sql2 可以检索列a 和列b,但实际上sql2 检索列abcderead_record 的所有列中,记录。很奇怪。
    • InnoDB 将整个记录存储在一起,所有列在同一页面上。要更新它的任何一列,必须先将整个页面读入缓冲池。
    • 谢谢比尔,但是 SELECT 将使用索引条件下推,sql1 只检索列a 和列b
    • 你看我的回答了吗? Using index 与索引条件下推不同。您显示的 EXPLAIN 输出并不表明它正在使用索引条件下推。
    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 2022-11-27
    • 2012-08-09
    • 2019-08-18
    • 2020-02-17
    • 2012-04-21
    相关资源
    最近更新 更多