MySQL 查詢條件中 in 會不會用到索引

當有人問你MySQL查詢條件中 in 會不會用到索引,你該怎麼回答?

答案: 可能會用到索引
動手來測試下

1.建立一張表,給字段port創建索引

CREATE TABLE `pre_request_logs_20180524` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` char(16) NOT NULL COMMENT '代理IP',
  `port` int(8) NOT NULL COMMENT '端口號',
  `status` enum('成功','失敗') NOT NULL COMMENT '狀態',
  `create_time` datetime NOT NULL COMMENT '建立時間',
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_port` (`port`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COMMENT='代理IP請求日誌';

插入測試數據sql

INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (1, '192.168.1.199', 53149, '失敗', '2018-05-24 14:55:34', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (2, '192.168.1.100', 10653, '成功', '2018-05-24 14:55:54', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (3, '192.168.1.112', 50359, '失敗', '2018-05-24 14:56:00', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (4, '192.168.1.67', 30426, '失敗', '2018-05-24 14:56:09', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (5, '192.168.1.209', 49323, '失敗', '2018-05-24 14:56:12', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (6, '192.168.1.209', 51161, '成功', '2018-05-24 14:56:13', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (7, '192.168.1.12', 54167, '成功', '2018-05-24 14:56:16', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (8, '192.168.1.64', 20462, '成功', '2018-05-24 14:56:19', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (9, '192.168.1.53', 22823, '失敗', '2018-05-24 14:56:31', '2018-11-16 10:58:13');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (10, '192.168.1.85', 48229, '成功', '2018-05-24 14:56:32', '2018-11-16 11:01:11');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (11, '192.168.1.85', 48229, '成功', '2018-05-24 14:56:32', '2018-11-16 11:01:15');
INSERT INTO ``(`id`, `ip`, `port`, `status`, `create_time`, `update_time`) VALUES (12, '192.168.1.85', 48229, '成功', '2018-05-24 14:56:32', '2018-11-16 13:34:37');

2.測試sql

explain select * from pre_request_logs_20180524 where port in (51161,20462,48229);

執行結果
clipboard.png
從結果來看是沒有用到索引,但不要着急下結論,再看二個sql測試

explain select * from pre_request_logs_20180524 where port in (51161,48229);
explain select * from pre_request_logs_20180524 where port in (51161,20462);

執行結果分別以下
clipboard.png優化

clipboard.png

能夠看到第二條sql是用到了索引,二條sql的區別在於port值不同,一個包含48229,一個包含20462spa

其實MySQL優化器會自動判斷in是否走二級索引,也就是port字段的索引
or 查詢和 in 同樣,都是可能會用到索引,能夠試下下面二條sql3d

explain select * from pre_request_logs_20180524 where port = 51161 or port = 20462;
explain select * from pre_request_logs_20180524 where port = 51161 or port = 48229;
相關文章
相關標籤/搜索