MySQL索引与优化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL索引与优化相关的知识,希望对你有一定的参考价值。
1. 性能下降,sql执行时间长原因:查询语句没写好,索引失效,关联太多join,服务器参数设置不合理(JoinBuffer大小,SortBuffer大小,最大连接数)
2. 使用join时应该小表驱动大表,小数据集驱动大数据集
3. 索引:索引是帮助mysql高效获取数据的一种数据结构,即索引的本质是数据结构。除了数据本身之外,MySQL数据库还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,这样就可以在这些数据结构的而基础上实现高效的数据查找算法,这种数据结构就是索引。
4. 一把来说索引本身也很大,因此往往以索引文件的形式存储在磁盘上。我们通常使用的索引一般都是B树(多路搜索树,不一定二叉树)结构组织的索引。
5. 索引的优缺点:
优点:使用索引查询可以提高数据检索效率,降低数据库IO成本;使用索引排序
可以降低数据排序的成本,降低了CPU的消耗。
缺点:索引实际上也是一张表,该表保存了主键与索引字段,并指向实体表的记
录,所以索引也会占用空间,虽然索引大大提高了查询速度,但是会降低
表的更新速度,例如insert,update,delete操作时除了更新表数据,还
需要更新索引。
6. 索引分为单值索引,唯一索引,复合索引
7. mysql常见瓶颈:
CPU:CPU饱和一般发生在数据装入内存或者从磁盘上读取数据的时候
IO:磁盘IO瓶颈一般发生在装入数据远大于内存容量的时候
服务器(linux)硬件性能的瓶颈:top,free,iostat和vmstat来查看系统的性能状态
8. 通过explain查看sql执行计划,分析是否可以优化。执行计划包含的信息有:
(1). id:select 查询的序列号,包含一组数字,表示查询中执行select子句或操作表
的顺序:如果id相同,执行顺序自上至下;如果id不同,如果是子查询,id的
序号会递增,id值越大优先级越高,越先被执行
(2). select_type:查询的类型,主要用于区别普通查询,联合查询,子查询等复杂
的查询。有以下可能值:
simple:简单查询,不包含子查询和union
primary:查询中若包含任何复杂的子部分,最外层的查询被标记为primary
subquery:select或者where中有子查询
derived:from中有子查询
union:union之后的查询
union result:从union表获取结果的select
(3). table 显示这一行的数据来自哪张表
(4). type:显示查询使用了哪种访问类型,从最好到最差依次为:
system>const>eq_ref>ref>range>index>All。
system : 表只有一行记录,const类型特例,基本不会出现
const : 表示索引依次就找到了。const用于比较primary key或者unique索引。
因为只匹配一行数据,所以能很快找到,例如将主键置于where条件
中,mysql就能将查询转换为一个常量
eq_ref : 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,
常见于主键或唯一性索引扫描
ref : 非唯一性索引扫描,返回匹配某个单独值的所有行。
range :检索给定范围。一般出现在where字句中有between,<,>,in等的查询
index : full index scan,遍历全部索引。虽然和下面出现的All都会扫描全表,
但是因为索引文件通常都比数据小,而且index是从索引文件中读取的,
而All是从硬盘中读取的
all : full table scan
(5).possible_keys:可能用在这张表中的索引,查询的字段上存在索引就会被列出来
(6).key:实际使用的索引。查询中如果使用了覆盖索引,则该索引和查询的字段重合
(7).key_len:索引使用的字节数
(8).ref:显示索引的哪一列被使用了,如果可能的话是一个常数。哪些列或常量被用于查找索引列上的值
(9).rows:根据表统计信息以及索引使用情况,大致算出找到所需的记录所需要读取的行数
(10).Extra:额外的重要信息。有以下可能值:
using filesort:无法利用索引完成的排序,出现这种情况很影响性能
using temporary:使用了临时表保存中间结果,对查询结果排序的时候使用了
临时表,常见于order by和group by,十分影响性能,必须优化
using index:使用了覆盖索引,避免访问了数据行,效率不错
using where:使用了where过滤
9. 索引优化:
(1).全职匹配:
(2).最佳左前缀原则:如果查询了多列,查询应该从索引的最左前列开始并且不要不要跳过索引中的列
(3).不在索引上做任何操作(计算,函数,类型转换(自动或手动)),否则会导致索引失效而转向全表扫描
(4).存储引擎不能使用索引中范围条件右边的列
(5).尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少或避免select *
(6).mysql在使用不等于(!=或者<>),is null,is not null 的时候无法使用索引会导致全表扫描
(7).like以通配符开头(like "%abc")会导致索引失效,但是百分号结尾不会(like "abc%"),解决like "%"开头的可以使用覆盖索引解决
(8).字符串不加引号会导致索引失效
(9).少用or,用它来连接会导致索引失效
(10).使用group by需谨慎,因为分组之前必先排序,有可能会导致临时表的产生
10. sql优化步骤:先找到查询慢的sql(通过慢查询日志抓取超过一定时间的sql)->explain分析sql->优化索引与查询语句->如果问题还没解决,使用show profile查看sql执行的资源消耗情况,然后如果sql已经最优,判断是否mysql服务器问题,根据情况调整相关参数。
以上是关于MySQL索引与优化的主要内容,如果未能解决你的问题,请参考以下文章