在调试时发现缓慢更新的原因(表有54545371行),我试过了:
explain UPDATE CellTable1015 SET value = (value * 1) WHERE entityId = 1 AND attributeId in (22, 3);
+----+-------------+---------------+------------+-------+---------------+--------+---------+-------------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------+------------+-------+---------------+--------+---------+-------------+---------+----------+-------------+
| 1 | UPDATE | CellTable1015 | NULL | range | ea_ix,eal_ix | eal_ix | 18 | const,const | 4930829 | 100.00 | Using where |
+----+-------------+---------------+------------+-------+---------------+--------+---------+-------------+---------+----------+-------------+
在key
列下,您可以看到使用了密钥eal_ix
但是当我在添加第三个attributeId attributeId in (22, 3, 2)
时尝试完全相同的查询时,不使用任何键。
explain UPDATE CellTable1015 SET value = (value * 1) WHERE entityId = 1 AND attributeId in (22, 3, 2);
+----+-------------+---------------+------------+------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------+------------+------+---------------+------+---------+------+----------+----------+-------------+
| 1 | UPDATE | CellTable1015 | NULL | ALL | ea_ix,eal_ix | NULL | NULL | NULL | 54545371 | 100.00 | Using where |
+----+-------------+---------------+------------+------+---------------+------+---------+------+----------+----------+-------------+
索引结构是:
show index from CellTable1015;
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| CellTable1015 | 1 | ea_ix | 1 | entityId | A | 54947 | NULL | NULL | YES | BTREE | | |
| CellTable1015 | 1 | ea_ix | 2 | attributeId | A | 87755 | NULL | NULL | YES | BTREE | | |
| CellTable1015 | 1 | eal_ix | 1 | entityId | A | 61210 | NULL | NULL | YES | BTREE | | |
| CellTable1015 | 1 | eal_ix | 2 | attributeId | A | 86116 | NULL | NULL | YES | BTREE | | |
| CellTable1015 | 1 | eal_ix | 3 | loc | A | 145572 | NULL | NULL | YES | BTREE | | |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
几个问题:
1.为什么MySQL不使用索引进行第二次查询?
2.对于第一个查询,MySQL实际上应该使用ea_ix
索引而不是eal_ix
索引。因为eal_ix
是为具有额外AND loc=2
条件的其他查询创建的。 ea_ix
是为attributeId
和entityId
创建的覆盖索引(此问题与作为副本链接的问题不同)。