5.4案例学习
5.4.1支持多种过滤条件
考虑表上all的选项,对查询优化:优化查询 索引中找平衡
建议将使用频率高的列作为前缀(即是选择性低)在查询是即使没该字段也要用上该字段
尽可能将需要做范围查找的列放到索引的后面
不能滥用,降性能:in条件,优化器做的组合以指数形式增加,达到一定数量不再执行计划评估,索引不能很好被利用,耗内存
缩进部分有个人理解,写的不对的地方请指出
5.4.2避免多个范围条件
5.4.3优化排序
数据量比较大,翻页翻到后面,order by和limit,费时,解决:反范式化、预先计算缓存
或延迟关联:通过覆盖索引查询返回需要的主键,据主键关联原表获取数据(上一篇有例子)
5.5维护索引和表
目的:
1、找到并修复损坏的表,2、维护准确的索引统计信息,3、减少碎片
5.5.1目的一
损坏的索引可能导致查询返回错误数据,莫须有的主键冲突、导致数据库崩溃等
check talbe(有些引擎不支持)找出表和索引的错误
repair table修复损坏的表,不是all引擎支持,如不支持,通过alter重建表
系统区域、行数据区域损坏:备份中恢复表、损坏文件中恢复数据
引擎表损坏:硬件问题、外部操作数据文件、不是查询的问题
遇到损坏:最重要找出原因,设置innodb_force_recovery进入InnoDB强制恢复模式修复数据
5.5.2更新索引统计信息
查询优化器通过两个API了解存储引擎的索引值分布,决定如何使用索引
1、records_in_range,向存储引擎传入两个边界值获取在这个范围大概有多少条记录
2、info,返回各种类型的数据,包括索引的基数(每个键值有多少条记录)
show index from table_name 查看索引基数;
cardinality索引列基数:显示存储引擎估算索引列有多少个不同的取值
mysql5.0及以后可information_schema.statistics查询这些信息(info出的信息)
MySQL优化器使用基于成本的模型,以查询需要扫描多少行 来衡量成本,如表无统计信息或不准确,优化器可能会做出错误的决定,可通过analyze_table重新生成统计信息解决
每种存储引擎实现索引统计信息的方式不同,需要analyze table 频率不同 运行成本不同
1、memory不存储统计信息
2、myisam将索引统计信息存储在磁盘,analyze table需进行一次全索引扫描来计算索引基数,锁表
3、直到mysql5.5,innodb不在磁盘存储索引统计信息,而是通过随机索引访问评估并将其存储在内存中
首先随机读取少量索引页面,为此样本计算索引的统计信息,通过innodb_stats_sample_pages设置样本页数据
InnoDB将在 表首次打开、执行analyze table 、表大小发生非常大的变化 计算索引统计信息
将在打开information_schema表、show table status 、show index、客户端开启自动补全功能时触发索引统计信息的更新(大量数据、很严重的问题 特别I/O慢时 锁),可关闭innodb_stats_on_metadat避免上述问题
更稳定执行计划、系统重启快速生成统计信息,可用系统表持久化these信息,percona5.1通innodb_use_sys_stats_table启用该特性,mysql5.6通innodb_analyze_is_persistent控制
关闭索引统计信息后需要周期性使用analyze table手动更新信息,否则 MySQL的脾气 你懂的
5.5.3减少索引和数据碎片
B-Tress索引可能碎片化,减低查询效率 : B-Tree需随机磁盘访问才能定位到叶子页
叶子页物理分布顺序且紧密,查询性能更好,否 范围查、索引覆盖扫描 速度会降
表的数据存储也可能碎片化:更复杂
行碎片:row fragmentation 行存储在多个地方的多个片段中
行间碎片:intranet-row fragmentation逻辑上顺序的页(或者)行在磁盘上不是顺序存的 (或者这两字是什么意思?)
全表扫描 聚簇索引扫描之类的操作很大影响
剩余空间碎片:free space fragmentation 数据页中有大量空余空间
消除碎片:
可通过执行optimize table或导出再导入重新整理数据(almost引擎)
不支持的引擎,通过alter table重建表(修改引擎)
对于MyIASM 通排序算法重建索引消除碎片
5.6总结
终于等到你♪(^∇^*)
选择索引和编写利用索引的查询时原则:
1、单行访问很慢,best读取的块中能包含尽可能多所需要的行
2、按顺序 访问 范围数据:尽量使用原生顺序 避免额外排序
1)不需多次磁盘寻道,2)按需要顺序读取 不再需额外排序操作,order by不需排序 将行按组聚合计算
3、索引覆盖 查询 很快,包含all列,不需回表,避免单行访问
判断索引合理性:
按响应时间对查询进行分析:
找出消耗max时间 或 给服务器压力max的查询(第3章),检查查询的schema sql 索引结构
判断是否有查询扫描了太多的行、做了很多额外的排序、使用临时表 、使用随机I/0访问数据、太多回表查
如果查询不能从all可能的索引中获益:
1、是否可建更合适的索引,2、是否可重写该查询
写给自己的话:及时回顾