数据库

mysql explain中extra的Using where/

2019-07-17  本文已影响0人  史小猿

表结构

CREATE TABLE `test` (
  `i1` int(11) NOT NULL DEFAULT '0',
  `i2` int(11) NOT NULL DEFAULT '0',
  `d` date DEFAULT NULL,
  `f` int(11) DEFAULT '0',
  PRIMARY KEY (`i1`,`i2`),
  KEY `IX_TEST_N1` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO TEST VALUES
(1, 1, '1998-01-01',1), (1, 2, '1999-01-01',2),
(1, 3, '2000-01-01',1), (1, 4, '2001-01-01',2),
(1, 5, '2002-01-01',1), (2, 1, '1998-01-01',2),
(2, 2, '1999-01-01',1), (2, 3, '2000-01-01',2),
(2, 4, '2001-01-01',1), (2, 5, '2002-01-01',2),
(3, 1, '1998-01-01',1), (3, 2, '1999-01-01',2),
(3, 3, '2000-01-01',1), (3, 4, '2001-01-01',2),
(3, 5, '2002-01-01',1), (4, 1, '1998-01-01',2),
(4, 2, '1999-01-01',1), (4, 3, '2000-01-01',2),
(4, 4, '2001-01-01',1), (4, 5, '2002-01-01',2),
(5, 1, '1998-01-01',1), (5, 2, '1999-01-01',2),
(5, 3, '2000-01-01',1), (5, 4, '2001-01-01',2),
(5, 5, '2002-01-01',1); 

个人推论

覆盖索引cover不了列内容并且
where 条件包含多个索引信息并且optimizer_switch='index_condition_pushdown=on
就会走Using index condition,engine会根据多个索引筛选数据。同样的条件如果optimizer_switch='index_condition_pushdown=off'; 就会走Using where

下图看起来我的推论是正确的,第一张图覆盖索引能cover 查询列内容,所以没有走icp

下图又一次证明我的推论是正确的,当optimizer_switch='index_condition_pushdown=off时和上图一样的语句走了Using where

但是看起来下图和我上边的结论相悖,为啥=查询就变成using where 而不是Using index condition,因为下图选中的key是PRIMARY(l1,l2),mysql优化器认为按照主键索引在engine筛选记录,然后把记录给到server让server根据d去过滤,性能更好,所以没有选择icp。

补充:而且并非全部WHERE条件都可以用ICP筛选,如果WHERE条件的字段不在索引列中,还是要读取整表的记录到Server端做WHERE过滤。

下面是博客Index Condition Pushdown中的两幅插图,形象的描述了使用ICP和不使用ICP,优化器的数据访问和提取的过程。



总结:所以mysql explain 的extra 是用来告诉你sql语句实际运行的优化选择,而最好不要根据语句和表结构去尝试反推出extra是什么。

参考资料

上一篇下一篇

猜你喜欢

热点阅读