8.2.1.10(多范围读取优化)
MRR:
当表很大并且没有存储在存储引擎的缓存中时,使用二级索引上的范围扫描读取行可能导致许多随机磁盘访问基表。通过磁盘扫描多范围读取(MRR),MySQL通过首先扫描二级索引并收集相关行的,尝试减少范围扫描的随机磁盘访问次数。然后对键进行排序,最后使用主键的顺序从基表中检索行。MRR目的是减少随机磁盘访问的次数,而不是实现基本表数据的更多顺序扫描。
8.2.1.13 ORDER BY优化
如果想使用 GROUP BY,但是想避免order by语句的开销,可以指定禁止排序
ORDER BY NULL
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL
原始filesort算法:
1.根据条件获取检索出的行
2.把每一行(排序键值和行ID)存入排序缓冲区中
3.缓冲区满了的话,在内存中进行排序并将其写入临时文件,保存一个指向已排序块的指针。
4.重复执行前面的步骤,直到查询出所有的行
5.每7个排序块合并到,另外一个文件,直到所有的块都写入第二个文件
6.重复上面的操作直到少于15个排序块
7.最后一次排序,只把行ID写入最终的文件
8.使用结果文件中的行ID按排序顺序读取行(再次读取数据库)。
modified filesort算法:
存储排序key和select中的字段,不需要再次检索数据库,但是如果检索的字段包括text或blob字段,不应该使用此算法
内存中的文件排列算法
SELECT ... FROM single_table ... ORDER BY non_index_column [DESC] LIMIT [M,]N;
服务器可避免使用合并文件:
1.扫描数据,按照排列顺序生成一个队列,队列满了之后就弹出一个数据
2.返回剩下的N行数据,如果M有值的话则跳过M条数据
8.2.1.19 避免全表扫描
什么情况下会出现全表扫描
1.表中的行数较少
2.没有正确的使用索引列
3.通过索引查询判断返回的数据量过大,使用全表扫描更快
8.2.4优化DML语句
1.为了优化插入速度,将许多小操作合并为一个大操作
从文本文件加载到数据库表时,请使用 LOAD DATA INFILE
。
2.如果锁定表格,一次执行多个更新比一次次执行更快。
8.4优化数据库结构
数据列:
1.优化数据列的大小,对于读写效率有巨大的提升,列小了索引占的空间也小了
2.尽可能声明列为非空
3.对于字符串索引,最好使用前缀索引
4.遵循第三范式
5.一个表分成多个表
6.可以设置成字符串列或者数字列,设计成数字列
7.使用相同的字符集进行比较,防止进行类型转换 varchar(10)与char(15)连表查询无法使用索引,varvhar(10)和char(10)可以
8.innodb使用随机值做主键最好按照升序来,连续的主键被物理地存储在彼此附近时,可以更快地插入和检索。
8