最近遇到这么一条查询:
SELECT * from t_o2o_tran_pay where merchant_id in (3719) AND store_id in (1020,1001,1024,1027,1036,1013,1035,1038,1030,1082,1094,1021,1048,1026,1028,1046,1042,1025,1090,1017,1152,1043,1032,1040,1022,1045,1087,1044,1088,1154,1050,1086,1033,1049,1153,1151,1039,1098,1099,1023,1015,1031,1029,1002,1096,1016,1037,1014,1008,1060,1150,1034,1010)
AND trade_status = 1 AND pay_total > 0 AND order_time BETWEEN "2018-11-30 00:00:00" AND "2018-11-30 23:59:59";
分析结果如下:
整个表大概 4000W 数据,这个 SQL 扫描 4.5W 行,花费 40 多秒。
然后,我强制使用了另一个索引,SQL 如下:
SELECT * from t_o2o_tran_pay force index(rpt_query) where merchant_id in (3719) AND store_id in (1020,1001,1024,1027,1036,1013,1035,1038,1030,1082,1094,1021,1048,1026,1028,1046,1042,1025,1090,1017,1152,1043,1032,1040,1022,1045,1087,1044,1088,1154,1050,1086,1033,1049,1153,1151,1039,1098,1099,1023,1015,1031,1029,1002,1096,1016,1037,1014,1008,1060,1150,1034,1010)
AND trade_status = 1 AND pay_total > 0 AND order_time BETWEEN "2018-11-30 00:00:00" AND "2018-11-30 23:59:59" limit 20;
分析结果如下:
这个 SQL 语句使用联合索引,一共扫描了 8.5w 行,却只花费了 0.047 秒。
为什么扫描行多的 SQL 查询反而比扫描行数少的 SQL 查询花费时间更短? MySQL 内部的优化机制又为什么会选择第一个 SQL 中的索引进行查询呢? google 一下也没有找到想要的答案,有大佬能解答一下这是为什么么?