索引是什么
官方定义:索引(Index)是帮助MySQL高效获取数据的数据结构。
所以索引是一种数据结构,可以理解为“排好序的快速查找数据结构”。一般来说,索引本身也很大,不可能全部存储在内存,因此往往以索引文件的形式存储在磁盘上。
我们平常所说的索引,如果没有特别指明,都是B树(多路搜索树,不一定是二叉树)索引。其中聚集索引、次要索引、复合索引、前缀索引、唯一索引默认都是使用B+树
优势
类似书本的目录,提高查找效率,降低数据库IO成本。
通过索引列对数据排序,降低数据排序成本,降低CPU消耗。
劣势
MySQL索引分类
基本语法
创建
//如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定length
CREATE [UNIQUE] INDEX indexName ON tableName(columnName(length));
ALTER tableName ADD [UNIQUE] INDEX [indexName] ON (columnName(length));
删除
DROP INDEX [indexName] ON tableName;
查看
SHOW INDEX FROM tableName;
哪些情况需要/不需要建索引
性能分析
explain
explain是什么?
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是怎么处理你的SQL语句的,使用explian+SQL可以看到以下信息
+------+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------+------+---------------+------+---------+------+------+-------+
id:包含一组数字,表示查询或者操作表的顺序。id相同,执行顺序由上至下;id不同,如果是子查询,id的序号会递增,id越大,被执行优先级越高。
select_type:查询的类型,主要用于区别普通查询、联合查询、子查询等的复杂查询
table:显示是哪张表
type:显示查询使用了何种类型
+------+-------+-------+-----+--------+--------+---------+------+
| ALL | index | range | ref | eq_ref | const | system | NULL |
+------+-------+-------+-----+--------+--------+---------+------+
从好到坏依次为:system>const>eq_ref>ref>range>index>ALL
一般来说最少要达到range级别。
possible_keys:查询涉及到的字段若存在索引,则该索引将被列出,但不一定被实际使用
key:实际使用的索引,若为NULL则没又使用索引。查询中若使用了覆盖索引,则该索引和查询的select字段重叠
key_len:表示索引中使用的字节数,在不损失准确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际长度。即是根据表定义计算而得,不是通过表内检索得出。
ref:显示索引的哪一列被使用了
rows:根据表统计信息及索引选用情况,大致估算出找到所需要的记录需要读取的行数
Extra:包含不适合在其它列显示,但十分重要的信息
避免索引失效
order by 关键字
ORDER BY子句,尽量使用Index方式排序,避免使用FileSort方式排序,MySQL支持Index和FileSot两种方式排序,Index效率高,它指MySQL扫描索引本身完成排序。FileSort方式效率较低。
ORDER BY满足两种情况会使用Index方式排序:1.ORDER BY子句使用索引最左前列;2.使用WHERE子句与ORDER BY子句条件列组合满足索引最左前列。
如果不在索引列上,FileSort有两种算法:双路排序和单路排序
双路排序:MySQL4.1之前使用的是双路排序,就是两次扫描磁盘,最终得到数据。先从磁盘取排序字段,在buffer进行排序,再从磁盘中取出其它字段。取一批数据要进行扫描,IO是很耗时的,所以在MySQL4.1之后出现了第二种改进的算法,单路排序
单路排序:从磁盘中读取查询的所有列,在buffer对它们进行排序,然后扫描排序后的列表进行输出。避免两次IO,但是使用了更多空间。
单路排序需要更多的空间,所以可以通过增大sort_buffer_size和max_length_for_sort_data这两个参数来优化排序
group by 关键字
GROUP BY实质上是先排序后分组,所以策略基本跟ORDER BY一样。当无法使用索引列来分组,可以通过增大sort_buffer_size和max_length_for_sort_data这两个参数来优化分组。
慢查询日志
当通过explain不能解决SQL查询慢的问题,可以通过开启慢查询日志来继续排查
//查看慢日志是否开启ON为开启,OFF为关闭
show variables like '%slow_query_log%'
//开启慢查询日志
set global slow_query_log='ON';
set global slow_query_log=1;
//关闭慢查询日志
set global slow_query_log='OFF';
set global slow_query_log=0;
//查询当前的慢查询多少秒算慢
show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
//设置查询SQL超过5秒,记录慢查询日志,设置后要重新连接或者开个会话才生效
set global long_query_time=5;
//查询有多少条慢查询
show global status like '%slow_queries%';
show profile
用来分析SQL语句执行的资源消耗情况,默认关闭状态,保存最近15次的运行结果
show variables like 'profiling';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling | OFF |
+---------------+-------+
//开启
set global profiling='ON';
set global profiling=1;
//关闭
set global profiling='OFF';
set global profiling=0;
show profiles;
+----------+------------+----------------------------------+
| Query_ID | Duration | Query |
+----------+------------+----------------------------------+
| 1 | 0.00019383 | select @@version_comment limit 1 |
| 2 | 0.00052840 | show variables like 'profiling' |
+----------+------------+----------------------------------+
show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000065 | 0.000030 | 0.000029 | 0 | 0 |
| checking permissions | 0.000009 | 0.000005 | 0.000005 | 0 | 0 |
| Opening tables | 0.000006 | 0.000003 | 0.000003 | 0 | 0 |
| After opening tables | 0.000013 | 0.000006 | 0.000006 | 0 | 0 |
| init | 0.000021 | 0.000011 | 0.000011 | 0 | 0 |
| optimizing | 0.000015 | 0.000008 | 0.000007 | 0 | 0 |
| executing | 0.000016 | 0.000008 | 0.000008 | 0 | 0 |
| end | 0.000009 | 0.000004 | 0.000004 | 0 | 0 |
| query end | 0.000006 | 0.000004 | 0.000003 | 0 | 0 |
| closing tables | 0.000005 | 0.000002 | 0.000003 | 0 | 0 |
| freeing items | 0.000008 | 0.000004 | 0.000004 | 0 | 0 |
| updating status | 0.000012 | 0.000007 | 0.000006 | 0 | 0 |
| cleaning up | 0.000007 | 0.000003 | 0.000003 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+
参数: