sql优化中的陷进

来源:互联网 发布:python 传参数 编辑:程序博客网 时间:2024/05/15 02:28

在日常sql优化中,一定会碰到这样的sql:

select  id,name,t_id,status,cdate    from t1 left join t2 on t1.id=t2.id where t1.t_id in ('','','','') and t1.status = 2 order by t2.cdate desc;

如果t_id选择性比较高,则建立的索引可能是 create index idx_tid on t1(t_id);  create index idx_cdate on t2(cdate);


  这样最后的执行计划,如果驱动表t1结果集比较大,t2只有1条结果,就可能是1条驱动数万条的结果,mysql还会用到tmp table 且不会排序。这里的陷阱就在于我们如果指定T2使用idx_cdate 索引,就会消掉临时表和排序,但是如果结果集T1最后过滤的结果集很小(5000左右),但是T2会很多(数十条),mysql优化器可能无法按照原来的计划执行,始终按照指定的索引执行,可能就会多次的嵌套循环,但是此时的临时表,已经很小,排序也很小,对性能的影响也就不会很大。这种类型的sql关键在于in后的带入值无法估计,所以会造成执行计划无法很好的完成这个任务。