建表语句
CREATE TABLE `t` (`id` int(11) NOT NULL AUTO_INCREMENT,`a` int(11) DEFAULT NULL,`b` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `a` (`a`),KEY `b` (`b`)
) ENGINE=InnoDB;
往表中插入10W条数据
delimiter ;;
create procedure idata()
begindeclare i int;set i=1;while(i<=100000)doinsert into t (`a`,`b`) values(i, i);set i=i+1;end while;
end;;
delimiter ;
call idata();
接着执行SQL语句
select * from t where a between 10000 and 20000;
由于a上有普通索引,索引优化器肯定会选择使用a索引,与explain一致
但是如果此时有另外一个事务开启了一致性视图,如下所示
session A在 session B 之前开启了一致性视图,并且没有提交,那么 此时的 undo log 不能被清理,虽然此时 session B 做了删除操作,但数据不会被真正的删除。因此,在session B 再次插入10W条数据后 此时 undo log 保存了 20W的版本信息,当前数据页的数据页无法被覆盖,只能用另外的数据页来存储数据
而此时的session B 的分析结果将会出现扫描 10W行的情况,走了全表扫描,并没有使用到索引 a
导致此现象产生的原因 是由于受一致性视图的影响,导致计算索引的区分度出现了偏差,预估了错误的扫描行锁,而索引a 非主键索引,还需要回表进行一次查询操作,多一次IO操作的代价使MySQL的优化器觉得不如走全表扫描
当发现MySQL出现明细的统计数据行数出现异常后,我们可以执行以下命令重新统计索引信息,解决采样导致的扫描行数出错的问题
analyze table t
基于上述的建表语句与数据,当我们执行下面的查询语句时,
explain select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1;
预期时扫描1001行,但实际上MySQL扫描了50191行,远远超出我们的预期,这是由于 oder by 和 limitd的影响:
使用 force index(a) 语句后,强制使用索引 a,这时候发现扫描的行数只有1000了,符合我们的预期,MySQL不得不作出正确的选择
explain select * from t force index(a) where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1
如果我们能让MySQL判断出,使用索引b的代价比索引a大,那么MySQL就能选择到正确的索引
所以,我们可以
explain select * from ( select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 100) tt limit 1
最初的SQL语句因为b不用排序,又有limit 1,从5w里只要找到一条就可以返回了,如果选择a,因为要排序,就要扫完1000条,然后才能排序,这成本明显太大,所以选择了b。但如果是limit 100,选择b,虽然不用排序,但找到第一条记录后,还要向后查询,看后面有没有满足条件的100个记录,从5w中找100个的成本就大于从1000找100个的成本了,所以选择a。其实limit 20就会选择a了
干扰order by判断
explain select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b,a limit 1
要求按照b,a排序,无论选择b索引还是a索引,都只需要再将另外一个字段排序(个人认为索引b已经对b排好序,再对a排序;索引a已经对a排好序,再对b排序成(b,a)。这两者数据库引擎按照同样的排序算法去排序,前者成本较小,但是数据库引擎并不能感知得了),所以扫描行数成了影响决策的主要条件。
PHP网站源码大运seo网站优化松岗网站制作龙岗阿里店铺托管大芬网站设计布吉网站设计光明优化宝安网站排名优化木棉湾网站优化按天计费福田SEO按效果付费丹竹头至尊标王坂田网站优化排名横岗建站宝安企业网站设计大运优化坑梓网站优化横岗网站定制爱联设计公司网站龙岗建站西乡网站seo优化惠州网站优化按天收费民治网站建设龙岗百度网站优化排名平湖模板推广丹竹头seo网站推广吉祥SEO按天扣费双龙营销型网站建设永湖seo优化爱联网络营销石岩网站优化按天扣费沙井企业网站建设歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运