场景 某业务小程序埋点数据 总数在500w行左右 占空间700m sql查询 1. SELECT * from shopwwi_blpoint where appid = 'XXXXX' and formaid=420 limit 10 查询时间是 7.6s 2. SELECT * from shopwwi_blpoint where appid = 'XXXXX' and formaid=420 limit 10 查询时间为0.01s 3 SELECT * from shopwwi_blpoint where formaid=420 limit 10 查询时间为2.8s 通过explain 分析 1 SIMPLE shopwwi_blpoint ref appid,from_id,wx_appid_dld appid 153 const 1940932 Using index condition; Using where 1 SIMPLE shopwwi_blpoint ref appid,wx_appid_dld appid 153 const 1940932 Using index condition 1 SIMPLE shopwwi_blpoint ALL from_id 3881868 Using where 从分析结果得知 混合两个条件的适合 appid走了索引 并且使用了where 条件查询 走appid的单独查询的适合 只走了索引 走formaid的适合 走了where条件 没走索引 扫描行数最多 但是耗时最久的是混合查询 其次是不走索引 最后才是完全走索引 CREATE TABLE `shopwwi_blpoint` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '记录id,主键', `bp_id` varchar(25) DEFAULT '' COMMENT '埋点ID', `pp_data` varchar(255) DEFAULT '' COMMENT '埋点数据', `appid` varchar(50) DEFAULT '' COMMENT 'appid', `userid` varchar(15) DEFAULT '' COMMENT 'userid', `dld` varchar(10) DEFAULT '' COMMENT 'dld', `wx_openid` varchar(50) DEFAULT '' COMMENT '微信openid', `wx_unionid` varchar(50) DEFAULT '' COMMENT '微信unionid', `add_time` int(11) DEFAULT '0' COMMENT '记录时间', `aid` varchar(30) DEFAULT '' COMMENT '产品aid', `formaid` varchar(10) DEFAULT '' COMMENT '活动类型id', PRIMARY KEY (`id`), KEY `wx_openid` (`wx_openid`), KEY `userid` (`userid`), KEY `appid` (`appid`), KEY `dp_id` (`bp_id`), KEY `from_id` (`formaid`) USING BTREE, KEY `wx_appid_dld` (`appid`,`dld`,`userid`,`wx_unionid`) USING BTREE, KEY `dld_wx_time` (`dld`,`wx_unionid`,`userid`,`add_time`) USING BTREE, KEY `indexaid` (`aid`) ) ENGINE=InnoDB AUTO_INCREMENT=5020830 DEFAULT CHARSET=utf8 COMMENT='埋点记录表'; 经查 数据的appid跟formaid都是varchar类型的数据 且都加了索引 猜测是否是跟索引的类型有关 警告查询 经过查询 与此无关 那接下来猜测是否为变量的隐形转换 就是mysql把420当成了数字 每条数据都转成数字比较 那么我们把420转成字符串 “420”,运行结果如下 扫描出850行 记录下降很明显 还是使用了where keylen也明显变短 为原来的五分之一 行数为原来的1/5000 1 SIMPLE shopwwi_blpoint ref appid,from_id,wx_appid_dld from_id 33 const 850 Using index condition; Using where 再看执行时间 0.013s 减少很明显 以后写代码 一定要注意数据类型先 防治发生同样的问题 既查询数据的类型需要跟数据表存储类型相同