Description:
The queries above are completely equivalent and yet they produce different optimizations.
The more advanced intersect optimization is only picked if constant expression simplification takes place. Similar behavior was observed with BKA. This points to an underlying issue with the optimizer which may prevent a wide range of queries from benefitting from better optimizations.
mysql> EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND (125 + 0) \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: C
type: index_merge
possible_keys: PRIMARY,int_key
key: int_key,PRIMARY
key_len: 5,4
ref: NULL
rows: 1
Extra: Using intersect(int_key,PRIMARY); Using where
1 row in set (0.00 sec)
mysql> EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND 125 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: C
type: ref
possible_keys: PRIMARY,int_key
key: int_key
key_len: 5
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
How to repeat:
SET SQL_MODE='NO_ENGINE_SUBSTITUTION';
CREATE TABLE `C` (
`pk` int(11) NOT NULL AUTO_INCREMENT,
`int_nokey` int(11) DEFAULT NULL,
`int_key` int(11) DEFAULT NULL,
`date_key` date DEFAULT NULL,
`date_nokey` date DEFAULT NULL,
`time_key` time DEFAULT NULL,
`time_nokey` time DEFAULT NULL,
`datetime_key` datetime DEFAULT NULL,
`datetime_nokey` datetime DEFAULT NULL,
`varchar_key` varchar(1) DEFAULT NULL,
`varchar_nokey` varchar(1) DEFAULT NULL,
PRIMARY KEY (`pk`),
KEY `int_key` (`int_key`),
KEY `date_key` (`date_key`),
KEY `time_key` (`time_key`),
KEY `datetime_key` (`datetime_key`),
KEY `varchar_key` (`varchar_key`,`int_key`)
) ENGINE=InnoDB;
INSERT INTO `C` VALUES (1,NULL,7,'2005-12-13','2005-12-13','20:20:53','20:20:53',NULL,NULL,'l','l'),(2,5,0,'2003-01-01','2003-01-01','13:53:03','13:53:03','2003-09-12 02:19:51','2003-09-12 02:19:51','k','k'),(3,9,2,'2003-03-05','2003-03-05','12:37:08','12:37:08','2006-07-13 12:22:41','2006-07-13 12:22:41',NULL,NULL),(4,3,NULL,'2001-01-25','2001-01-25','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','u','u'),(5,134,122,'2003-03-17','2003-03-17','15:59:14','15:59:14','2000-10-03 15:17:43','2000-10-03 15:17:43','e','e'),(6,NULL,NULL,'2004-09-14','2004-09-14','04:43:51','04:43:51','2009-04-25 16:10:46','2009-04-25 16:10:46','v','v'),(7,1,1,NULL,NULL,'06:49:25','06:49:25','2005-01-11 03:31:23','2005-01-11 03:31:23','i','i'),(8,4,7,'2009-10-17','2009-10-17','15:25:21','15:25:21','2002-12-22 17:39:46','2002-12-22 17:39:46',NULL,NULL),(9,1,2,'2006-11-04','2006-11-04','18:16:04','18:16:04','2007-06-18 19:09:43','2007-06-18 19:09:43','u','u'),(10,0,7,'0000-00-00','0000-00-00','00:00:00','00:00:00','2001-06-14 20:33:16','2001-06-14 20:33:16','f','f'),(11,NULL,9,'2007-04-19','2007-04-19','18:36:41','18:36:41','2005-03-06 05:45:38','2005-03-06 05:45:38','u','u'),(12,8,6,'2003-08-18','2003-08-18','18:50:55','18:50:55','2000-10-01 17:07:48','2000-10-01 17:07:48','m','m'),(13,224,127,'2008-06-19','2008-06-19',NULL,NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00','j','j'),(14,90,198,'0000-00-00','0000-00-00','08:22:36','08:22:36','2002-02-13 21:59:10','2002-02-13 21:59:10','f','f'),(15,NULL,217,'2004-01-02','2004-01-02',NULL,NULL,'2008-09-21 04:36:56','2008-09-21 04:36:56','v','v'),(16,2,6,'2007-08-12','2007-08-12','09:37:21','09:37:21',NULL,NULL,'j','j'),(17,6,4,'2009-02-28','2009-02-28','03:03:26','03:03:26','2007-04-18 12:09:11','2007-04-18 12:09:11','g','g'),(18,6,8,'2008-08-01','2008-08-01','23:43:45','23:43:45','2001-12-25 21:55:34','2001-12-25 21:55:34','p','p'),(19,160,213,'2002-05-11','2002-05-11','08:19:59','08:19:59','2008-12-21 20:51:04','2008-12-21 20:51:04','u','u'),(20,3,1,NULL,NULL,'15:32:13','15:32:13','2007-05-06 06:09:03','2007-05-06 06:09:03',NULL,NULL);
EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND (125 + 0)
EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key`
BETWEEN 125 AND (125);
Description: The queries above are completely equivalent and yet they produce different optimizations. The more advanced intersect optimization is only picked if constant expression simplification takes place. Similar behavior was observed with BKA. This points to an underlying issue with the optimizer which may prevent a wide range of queries from benefitting from better optimizations. mysql> EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND (125 + 0) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: C type: index_merge possible_keys: PRIMARY,int_key key: int_key,PRIMARY key_len: 5,4 ref: NULL rows: 1 Extra: Using intersect(int_key,PRIMARY); Using where 1 row in set (0.00 sec) mysql> EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND 125 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: C type: ref possible_keys: PRIMARY,int_key key: int_key key_len: 5 ref: const rows: 1 Extra: Using where 1 row in set (0.00 sec) How to repeat: SET SQL_MODE='NO_ENGINE_SUBSTITUTION'; CREATE TABLE `C` ( `pk` int(11) NOT NULL AUTO_INCREMENT, `int_nokey` int(11) DEFAULT NULL, `int_key` int(11) DEFAULT NULL, `date_key` date DEFAULT NULL, `date_nokey` date DEFAULT NULL, `time_key` time DEFAULT NULL, `time_nokey` time DEFAULT NULL, `datetime_key` datetime DEFAULT NULL, `datetime_nokey` datetime DEFAULT NULL, `varchar_key` varchar(1) DEFAULT NULL, `varchar_nokey` varchar(1) DEFAULT NULL, PRIMARY KEY (`pk`), KEY `int_key` (`int_key`), KEY `date_key` (`date_key`), KEY `time_key` (`time_key`), KEY `datetime_key` (`datetime_key`), KEY `varchar_key` (`varchar_key`,`int_key`) ) ENGINE=InnoDB; INSERT INTO `C` VALUES (1,NULL,7,'2005-12-13','2005-12-13','20:20:53','20:20:53',NULL,NULL,'l','l'),(2,5,0,'2003-01-01','2003-01-01','13:53:03','13:53:03','2003-09-12 02:19:51','2003-09-12 02:19:51','k','k'),(3,9,2,'2003-03-05','2003-03-05','12:37:08','12:37:08','2006-07-13 12:22:41','2006-07-13 12:22:41',NULL,NULL),(4,3,NULL,'2001-01-25','2001-01-25','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','u','u'),(5,134,122,'2003-03-17','2003-03-17','15:59:14','15:59:14','2000-10-03 15:17:43','2000-10-03 15:17:43','e','e'),(6,NULL,NULL,'2004-09-14','2004-09-14','04:43:51','04:43:51','2009-04-25 16:10:46','2009-04-25 16:10:46','v','v'),(7,1,1,NULL,NULL,'06:49:25','06:49:25','2005-01-11 03:31:23','2005-01-11 03:31:23','i','i'),(8,4,7,'2009-10-17','2009-10-17','15:25:21','15:25:21','2002-12-22 17:39:46','2002-12-22 17:39:46',NULL,NULL),(9,1,2,'2006-11-04','2006-11-04','18:16:04','18:16:04','2007-06-18 19:09:43','2007-06-18 19:09:43','u','u'),(10,0,7,'0000-00-00','0000-00-00','00:00:00','00:00:00','2001-06-14 20:33:16','2001-06-14 20:33:16','f','f'),(11,NULL,9,'2007-04-19','2007-04-19','18:36:41','18:36:41','2005-03-06 05:45:38','2005-03-06 05:45:38','u','u'),(12,8,6,'2003-08-18','2003-08-18','18:50:55','18:50:55','2000-10-01 17:07:48','2000-10-01 17:07:48','m','m'),(13,224,127,'2008-06-19','2008-06-19',NULL,NULL,'0000-00-00 00:00:00','0000-00-00 00:00:00','j','j'),(14,90,198,'0000-00-00','0000-00-00','08:22:36','08:22:36','2002-02-13 21:59:10','2002-02-13 21:59:10','f','f'),(15,NULL,217,'2004-01-02','2004-01-02',NULL,NULL,'2008-09-21 04:36:56','2008-09-21 04:36:56','v','v'),(16,2,6,'2007-08-12','2007-08-12','09:37:21','09:37:21',NULL,NULL,'j','j'),(17,6,4,'2009-02-28','2009-02-28','03:03:26','03:03:26','2007-04-18 12:09:11','2007-04-18 12:09:11','g','g'),(18,6,8,'2008-08-01','2008-08-01','23:43:45','23:43:45','2001-12-25 21:55:34','2001-12-25 21:55:34','p','p'),(19,160,213,'2002-05-11','2002-05-11','08:19:59','08:19:59','2008-12-21 20:51:04','2008-12-21 20:51:04','u','u'),(20,3,1,NULL,NULL,'15:32:13','15:32:13','2007-05-06 06:09:03','2007-05-06 06:09:03',NULL,NULL); EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND (125 + 0) EXPLAIN SELECT `datetime_key` FROM C WHERE `pk` < 128 AND `int_key` BETWEEN 125 AND (125);