p177~p228. 分2次, p177~p197, p198~p228. 此为第2次.
性能分析语句
explain extended select * from table; show warnings;
查询有2个结果, 结果1是查询的方式, 是全表扫描还是索引查询. 结果2是优化后的语句.
聚簇索引
又叫聚集索引. Innodb中这个索引用来定义数据存储的地方, 即数据的存储位置与这个索引直接相关. 也意味者索引值相近的数据存放的比较近.
- 小. 值类型的大小尽量小, 这样一个页可存放更多的索引. 要求不高的表推荐用int自增, 分布式可以用雪花算法给一个有序long值作为聚集索引.
- 有序. 新插入的数据的聚集索引尽量有序, 即插入到最后, 这样其他数据不需要移动. 反例就是以无序Guid作为聚集索引, 每次插入新数据都会对现有数据进行移动, 导致效率低下.
- 二级索引, 又叫非聚集索引, 保存的是二级索引值+聚集索引值, 所以二级索引要做2次查询才能查到整个数据行, 先查出聚集索引值, 再按聚聚索引查询, 查出数据行.
覆盖索引
即索引不光覆盖where的部分, 还覆盖select的部分, 这样查询不用查表, 直接查索引就结束了. 用explain语句查出的结果extra中using index
即是覆盖索引的情况.
- 二级索引包含主键, 所以select部分可以包含主键, 也是覆盖索引. 如定义了key(name), 则select name,id from table也是覆盖索引的情况.
索引排序
只有索引列的顺序与ORDER BY的顺序完全一致, 且所有列的排序方向都一致时, 才能用索引排序. 用explain语句查出的结果type中index
即是索引排序的情况.
- 多列索引, key(a,b,c), select * from table order by a, b, c才可使用索引排序.
- 当前缀为常数时, 也可以使用索引排序. select * from table where a='xx' order by b,c.
冗余和重复索引
通过语句select * from information_schema.STATISTICS;
可以查看全局的索引情况, 并分析哪些是重复索引.
- 在一个表中定义UNIQUE(a)与INDEX(a)是重复的, 因为唯一性也是靠索引实现的. 多加了索引会导致索引变大, 搜索变慢.
- 删除索引可以用
alter table table_name drop key index_name;
, 由于删除索引有风险, 所以mysql8.0支持隐藏索引,alter table t alter index idx_a invisible[visible];
重建索引和整理碎片
先说下tablespace的概念, 从mysql5.6之后, 默认开启innodb_file_per_table
选项, 单个表单个文件存储, 即每个表都是一个文件, 这样可以提升文件读写的效率以及维护便利等好处. 参考链接.
在开启tablespace后, 执行语句select * from information_schema.tables
可以查看每张表的数据及碎片情况. 关于这个表可查看mysql手册.
DATA_LENGTH
表示数据大小,INDEX_LENGTH
表示索引大小,DATA_FREE
表示剩余空间大小, 一般来说DATA_FREE很大的话, 就是碎片比较多, 需要整理.alter table table_name engine=Innodb;
可以进行索引重建