在实际的sql底层执行时:会将我们的sql语句通过解析器进行解析,判断是否有sql语法错误,语法无误则将其转换为sql查询树,通过优化器去判断是否走索引,走哪些索引比较快,最后通过我们具体的执行引擎(innodb或mysalam等)进行执行。
架构共性总结:在JVM加载类或是Mysql运行sql,首先都会去校验我们写的代码是否符合其规范,在一切符合规范的前提下,才会进行下一步的操作流程。在我们日常写代码过程中,这种先校验的方法,值得借鉴,切忌偷懒!
2.1 排序在MYSQL中的优化
单路排序:所有的字段都放在sort_buffer缓存中,对sort_buffer中的数据按照指定字段进行排序;
双路排序:将主键id和排序字段放到sort_buffer中,对sort_buffer中的数据按照id和排序字段进行排序。遍历排好序的id和排序字段,按照id的值回到原表中取出所有的值返回给客户端。
区别:单路不需要回表,双路需要回表。MYSQL通过max_length_for_sort_data这个参数来控制排序,在不同场景使用不同排序,从而提高效率(一般max_length_for_sort_data<1024字节,使用单路排序)。但注意:非专业的DBA不要轻易调整,未必有MYSQL自己优化的好!
2.2 分页在MYSQL中的优化
当表中数据足够大时,我们发现翻前几页很快,但越往后,比如100页,响应越慢,例如下面这条sql(其中name为索引字段)在MYSQL中是如何执行的呢?
SELECt * FROM employees ORDER BY name LIMIT 100,100;
从100页开始取100条数据,MYSQL是查询出前10100条数据,然后将前10000条数据截取剔除,保留后面的100条返回。但上述SQL使用EXPLAIN执行后发现并没有走name索引字段,因为扫描整个索引并查找到没索引的行(2.1中提到的单路排序!遍历多个索引树的成本比扫描全表的成本更高,优化器放弃使用索引)现在知道没有走索引,优化关键:让排序时返回的字段尽可能少!(双路排序)
SELECt * FROM employees e INNER JOIN (SELECt id FROM employees ORDER BY name LIMIT 100,100) ed ON e.id=ed.id;
优化后时间缩短一半!
2.3 索引设计原则
1)代码先行、索引后上
并非建完表就立马建索引,一般是主体业务功能开发完,把涉及到该表相关的sql都要拿出来分析之后在建立索引。
2)联合索引尽量覆盖条件
即每一个联合索引尽量去sql语句里的where、order by、group by的字段,还要确保这些字段顺序尽量满足sql查询的最左前缀原则。
3)不要在小基数字段上建立索引
索引基数指这个字段在表里有多少个不同的值,比如一张表里有100万的数据,其中性别字段不是男就是女,那么该字段基数就是2,这种小基数建索引,还不如全表扫描来的快。
4)长字符串采用前缀索引
比如一个字段里截取前20位作为索引



