MySQL 创建索引的原则,优化的思路

这篇具有很好参考价值的文章主要介绍了MySQL 创建索引的原则,优化的思路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

康师傅yyds

MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。
从 功能逻辑 上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。
按照 物理实现方式 ,索引可以分为 2 种:聚簇索引和非聚簇索引。
按照 作用字段个数 进行划分,分成单列索引和联合

创建索引的原则

1     show index from    channel_detail;
2     DROP INDEX idx_cl_channel_id ON channel_label;
3 
4 CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
5 ON table_name (col_name[length],...) [ASC | DESC]
6     CREATE INDEX idx_cd_channel_id ON channel_detail(channel_id);

查询某表索引使用情况

SELECT object_type,object_schema,object_name,index_name,count_star,count_read,COUNT_FETCH
FROM
`performance_schema`.table_io_waits_summary_by_index_usage where object_name='orders_1';

 文章来源地址https://www.toymoban.com/news/detail-710748.html

select * from schema_unused_indexes; // 在sys库中查看没用的索引

 

适合创建索引的情况

    1、字段的数值有唯一性的限制
      业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。(来源:Alibaba)
  说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的。
 
    2、频繁作为 WHERE 查询条件的字段
    3. 经常 GROUP BY 和 ORDER BY 的列
    4、UPDATE、DELETE 的 WHERE 条件列
      如果进行更新的时候,更新的字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护。
    5.DISTINCT 字段需要创建索引

      对某个字段去重,要对该字段创索引

    6. 多表 JOIN 连接操作时,创建索引注意事项
      首先, 连接表的数量尽量不要超过 3 张
      其次, 对 WHERE 条件创建索引
      最后, 对用于连接的字段创建索引
    7. 使用列的类型小的创建索引

      能用小一点的数据类型就用小一点的   int->bigint,InnoDB创建的索引B-tree小一点,查的快一点

    8. 使用字符串前缀创建索引

      对字符串创建索引时,截取一部分前缀就可以了。

   Alibaba《Java开发手册》
      【 强制 】在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
        说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会 高达90% 以上 ,可以使用 count(distinct left(列名, 索引长度))/count(*)的区分度来确定。
    9. 区分度高(散列性高)的列适合作为索引      
    10. 使用最频繁的列放到联合索引的左侧
    11. 在多个字段都要创建索引的情况下,联合索引优于单值索引

 

不适合创建索引的情况

    where不到的字段不创建
    重复数据太多的不创建(如不要对 is_delete 字段创建索引)
    数据量小的表不要创建索引
    经常更新操作的表不要创建太多索引
    不建议用无须的字段撞见索引
      例如身份证、UUID(在索引比较时需要转为ASCII,并且插入时可能造成页分裂)、MD5、HASH、无序长字符串等。
    不要定义冗余或重复的索引

      重点提现在联合索引和单行索引的重复上

 

SQL优化的思路

 

1、SHOW INDEX FROM student_info; //查表中索引
2、DROP INDEX index_name ON table_name; //删除索引
3、set global slow_query_log='ON'; //开启慢查询日志 不用的时候,最好关闭掉。
4、set global long_query_time = 1; //修改long_query_time阈值为一秒  默认我们本地超过一秒为慢查询
  set long_query_time=1; //上面修改了全局的,还要修改当前回话的
5、show variables like '%slow_query_log%'; // 查看两个参数
6、SHOW GLOBAL STATUS LIKE '%Slow_queries%'; //查看慢查询的次数

 数据库重启的话,上面参数要重新设置,可以去配置文件中设置。

慢查询分析工具mysqldumpslow

mysqldumpslow 命令的具体参数如下:
-a: 不将数字抽象成N,字符串抽象成S
-s: 是表示按照何种方式排序:
  c: 访问次数
  l: 锁定时间
  r: 返回记录
  t: 查询时间
  al:平均锁定时间
  ar:平均返回记录数
  at:平均查询时间 (默认方式)
ac:平均查询次数
-t: 即为返回前面多少条的数据;
-g: 后边搭配一个正则匹配模式,大小写不敏感的;
 
show variables like "%slow%"; // 查询慢查询日志设置

 show status like "%slow%"; -- 查询慢查询SQL状况;
 show variables like "long_query_time"; -- 慢查询时间

 

mysql配置文件 /etc/my.cnf

slow_query_log = on -- 开启日志;
slow_query_log_file = /data/f/mysql_slow_cw.log -- 记录日志的log文件; 注意:window上必须写绝对路径,比如 D:/wamp/bin/mysql/mysql5.5.16/data/show-slow.log
long_query_time = 2 -- 最长查询的秒数;
log-queries-not-using-indexes -- 表示记录没有使用索引的查询

 


mysqldumpslow -s t -t 5 /var/lib/mysql/atguigu01-slow.log //按照查询时间排序,查看查的最慢的前五条 SQL 语句

  #得到返回记录集最多的10个SQL
 mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log
  #得到访问次数最多的10个SQL
 mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log
  #得到按照时间排序的前10条里面含有左连接的查询语句
 mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log
  #另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况
 mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more
 

分析查询语句:EXPLAIN

show variables like 'profiling'; //查看 SQL 执行成本:SHOW PROFILE
  set profiling = 'ON';  //设置 profiling='ON’ 来开启 show profile
  show profiles; //执行相关的查询语句。接着看下当前会话都有哪些 profiles
  show profile; //查看最近一次查询的开销
  show profile cpu,block io for query 2; //查询编号2的sql开销

 

EXPLAIN SELECT select_options;

EXPLAIN 各列

MySQL 创建索引的原则,优化的思路

 

数据表,s1、s2 相同的

 1 CREATE TABLE s1 (
 2 id INT AUTO_INCREMENT,
 3 key1 VARCHAR(100),
 4 key2 INT,
 5 key3 VARCHAR(100),
 6 key_part1 VARCHAR(100),
 7 key_part2 VARCHAR(100),
 8 key_part3 VARCHAR(100),
 9 common_field VARCHAR(100),
10 PRIMARY KEY (id),
11 INDEX idx_key1 (key1),
12 UNIQUE INDEX idx_key2 (key2),
13 INDEX idx_key3 (key3),
14 INDEX idx_key_part(key_part1, key_part2, key_part3)
15 ) ENGINE=INNODB CHARSET=utf8;

 

 

 table:表名

#1. table:表名
#查询的每一行记录都对应着一个单表
EXPLAIN SELECT * FROM s1;


SHOW INDEX FROM s1;


#s1:驱动表 s2:被驱动表
EXPLAIN SELECT * FROM s1 INNER JOIN s2;


id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id
id如果相同,可以认为是一组,从上往下顺序执行
在所有组中,id值越大,优先级越高,越先执行
关注点:id号每个号码,表示一趟独立的查询, 一个sql的查询趟数越少越好 
 1 #2. id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id
 2  SELECT * FROM s1 WHERE key1 = 'a';
 3 
 4 
 5  SELECT * FROM s1 INNER JOIN s2
 6  ON s1.key1 = s2.key1
 7  WHERE s1.common_field = 'a';
 8 
 9 
10  SELECT * FROM s1 
11  WHERE key1 IN (SELECT key3 FROM s2);
12 
13 
14  SELECT * FROM s1 UNION SELECT * FROM s2;
15 
16 
17  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
18  
19  
20  EXPLAIN SELECT * FROM s1 INNER JOIN s2;
21  
22  
23  EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';
24  
25  ######查询优化器可能对涉及子查询的查询语句进行重写,转变为多表查询的操作########
26  EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key2 FROM s2 WHERE common_field = 'a');
27  
28  #Union去重
29  EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;
30  
31  
32  EXPLAIN SELECT * FROM s1  UNION ALL SELECT * FROM s2;
select_type:SELECT关键字对应的那个查询的类型,确定小查询在整个大查询中扮演了一个什么角色

MySQL 创建索引的原则,优化的思路

 1 #3. select_type:SELECT关键字对应的那个查询的类型,确定小查询在整个大查询中扮演了一个什么角色
 2  
 3  # 查询语句中不包含`UNION`或者子查询的查询都算作是`SIMPLE`类型
 4  EXPLAIN SELECT * FROM s1;
 5  
 6  
 7  #连接查询也算是`SIMPLE`类型
 8  EXPLAIN SELECT * FROM s1 INNER JOIN s2;
 9  
10  
11  #对于包含`UNION`或者`UNION ALL`或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个
12  #查询的`select_type`值就是`PRIMARY`
13  
14  
15  #对于包含`UNION`或者`UNION ALL`的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询
16  #以外,其余的小查询的`select_type`值就是`UNION`
17  
18  #`MySQL`选择使用临时表来完成`UNION`查询的去重工作,针对该临时表的查询的`select_type`就是
19  #`UNION RESULT`
20  EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;
21  
22  EXPLAIN SELECT * FROM s1 UNION ALL SELECT * FROM s2;
23  
24  #子查询:
25  #如果包含子查询的查询语句不能够转为对应的`semi-join`的形式,并且该子查询是不相关子查询。
26  #该子查询的第一个`SELECT`关键字代表的那个查询的`select_type`就是`SUBQUERY`
27  EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';
28  
29  
30  #如果包含子查询的查询语句不能够转为对应的`semi-join`的形式,并且该子查询是相关子查询,
31  #则该子查询的第一个`SELECT`关键字代表的那个查询的`select_type`就是`DEPENDENT SUBQUERY`
32  EXPLAIN SELECT * FROM s1 
33  WHERE key1 IN (SELECT key1 FROM s2 WHERE s1.key2 = s2.key2) OR key3 = 'a';
34  #注意的是,select_type为`DEPENDENT SUBQUERY`的查询可能会被执行多次。
35  
36  
37  #在包含`UNION`或者`UNION ALL`的大查询中,如果各个小查询都依赖于外层查询的话,那除了
38  #最左边的那个小查询之外,其余的小查询的`select_type`的值就是`DEPENDENT UNION`。
39  EXPLAIN SELECT * FROM s1 
40  WHERE key1 IN (SELECT key1 FROM s2 WHERE key1 = 'a' UNION SELECT key1 FROM s1 WHERE key1 = 'b');
41  
42  
43  #对于包含`派生表`的查询,该派生表对应的子查询的`select_type`就是`DERIVED`
44  EXPLAIN SELECT * 
45  FROM (SELECT key1, COUNT(*) AS c FROM s1 GROUP BY key1) AS derived_s1 WHERE c > 1;
46  
47  
48  #当查询优化器在执行包含子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,
49  #该子查询对应的`select_type`属性就是`MATERIALIZED`
50  EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2); #子查询被转为了物化表
 partition:匹配的分区信息
 type:针对单表的访问方法
小结:
结果值从最好到最坏依次是: system > const > eq_ref > ref > fulltext > ref_or_null > index_merge >
unique_subquery > index_subquery > range > index > ALL 其中比较重要的几个提取出来(见上图中的蓝
色)。SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,最好是 consts级别。(阿里巴巴
开发手册要求) 
 1 # 5. type:针对单表的访问方法
 2  
 3  #当表中`只有一条记录`并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,
 4  #那么对该表的访问方法就是`system`。
 5  CREATE TABLE t(i INT) ENGINE=MYISAM;
 6  INSERT INTO t VALUES(1);
 7  
 8  EXPLAIN SELECT * FROM t;
 9  
10  #换成InnoDB    ALL
11  CREATE TABLE tt(i INT) ENGINE=INNODB;
12  INSERT INTO tt VALUES(1);
13  EXPLAIN SELECT * FROM tt;
14  
15  
16  #当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是`const`
17  EXPLAIN SELECT * FROM s1 WHERE id = 10005;
18  
19  EXPLAIN SELECT * FROM s1 WHERE key2 = 10066;
20  
21  
22  #在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的
23  #(如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则
24  #对该被驱动表的访问方法就是`eq_ref`
25  EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;
26   
27   
28  #当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是`ref`
29  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
30  
31  
32  #当对普通二级索引进行等值匹配查询,该索引列的值也可以是`NULL`值时,那么对该表的访问方法
33  #就可能是`ref_or_null`
34  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key1 IS NULL;
35  
36  
37  #单表访问方法时在某些场景下可以使用`Intersection`、`Union`、
38  #`Sort-Union`这三种索引合并的方式来执行查询
39  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key3 = 'a';
40  
41  
42  #`unique_subquery`是针对在一些包含`IN`子查询的查询语句中,如果查询优化器决定将`IN`子查询
43  #转换为`EXISTS`子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的`type`
44  #列的值就是`unique_subquery`
45  EXPLAIN SELECT * FROM s1 
46  WHERE key2 IN (SELECT id FROM s2 WHERE s1.key1 = s2.key1) OR key3 = 'a';
47  
48  
49  #如果使用索引获取某些`范围区间`的记录,那么就可能使用到`range`访问方法
50  EXPLAIN SELECT * FROM s1 WHERE key1 IN ('a', 'b', 'c');
51  
52  #同上
53  EXPLAIN SELECT * FROM s1 WHERE key1 > 'a' AND key1 < 'b';
54  
55  
56  #当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是`index`
57  EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a';
58  
59  
60  #最熟悉的全表扫描
61  EXPLAIN SELECT * FROM s1;
 possible_keys和key:可能用到的索引 和  实际上使用的索引
key_len:实际使用到的索引长度(即:字节数)
 1 #7.  key_len:实际使用到的索引长度(即:字节数)
 2 # 帮你检查`是否充分的利用上了索引`,`值越大越好`,主要针对于联合索引,有一定的参考意义。
 3  EXPLAIN SELECT * FROM s1 WHERE id = 10005;
 4 
 5 
 6  EXPLAIN SELECT * FROM s1 WHERE key2 = 10126;
 7 
 8 
 9  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
10 
11 
12  EXPLAIN SELECT * FROM s1 WHERE key_part1 = 'a';
13 
14  
15  EXPLAIN SELECT * FROM s1 WHERE key_part1 = 'a' AND key_part2 = 'b';
16 
17  EXPLAIN SELECT * FROM s1 WHERE key_part1 = 'a' AND key_part2 = 'b' AND key_part3 = 'c';
18  
19  EXPLAIN SELECT * FROM s1 WHERE key_part3 = 'a';
20  
21 #练习:
22 #varchar(10)变长字段且允许NULL  = 10 * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)+2(变长字段)
23 
24 #varchar(10)变长字段且不允许NULL = 10 * ( character set:utf8=3,gbk=2,latin1=1)+2(变长字段)
25 
26 #char(10)固定字段且允许NULL    = 10 * ( character set:utf8=3,gbk=2,latin1=1)+1(NULL)
27 
28 #char(10)固定字段且不允许NULL  = 10 * ( character set:utf8=3,gbk=2,latin1=1)
 ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息。
 1 # 8. ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息。
 2  #比如只是一个常数或者是某个列。
 3  
 4  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
 5  
 6  
 7  EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;
 8  
 9  
10  EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s2.key1 = UPPER(s1.key1);

 

rows:预估的需要读取的记录条数
1  # 9. rows:预估的需要读取的记录条数
2  # `值越小越好`
3  EXPLAIN SELECT * FROM s1 WHERE key1 > 'z';

 

 

filtered: 某个表经过搜索条件过滤后剩余记录条数的百分比
 1 # 10. filtered: 某个表经过搜索条件过滤后剩余记录条数的百分比
 2  
 3  #如果使用的是索引执行的单表扫描,那么计算时需要估计出满足除使用
 4  #到对应索引的搜索条件外的其他搜索条件的记录有多少条。
 5  EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND common_field = 'a';
 6  
 7  
 8  #对于单表查询来说,这个filtered列的值没什么意义,我们`更关注在连接查询
 9  #中驱动表对应的执行计划记录的filtered值`,它决定了被驱动表要执行的次数(即:rows * filtered)
10  EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.key1 = s2.key1 WHERE s1.common_field = 'a';

 

 

 Extra:一些额外的信息

 

 1 #11. Extra:一些额外的信息
 2  #更准确的理解MySQL到底将如何执行给定的查询语句
 3  
 4  
 5  #当查询语句的没有`FROM`子句时将会提示该额外信息
 6  EXPLAIN SELECT 1;
 7  
 8  
 9  #查询语句的`WHERE`子句永远为`FALSE`时将会提示该额外信息
10  EXPLAIN SELECT * FROM s1 WHERE 1 != 1;
11  
12  
13  #当我们使用全表扫描来执行对某个表的查询,并且该语句的`WHERE`
14  #子句中有针对该表的搜索条件时,在`Extra`列中会提示上述额外信息。
15  EXPLAIN SELECT * FROM s1 WHERE common_field = 'a';
16  
17  
18  #当使用索引访问来执行对某个表的查询,并且该语句的`WHERE`子句中
19  #有除了该索引包含的列之外的其他搜索条件时,在`Extra`列中也会提示上述额外信息。
20  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' AND common_field = 'a';
21  
22  
23  #当查询列表处有`MIN`或者`MAX`聚合函数,但是并没有符合`WHERE`子句中
24  #的搜索条件的记录时,将会提示该额外信息
25  EXPLAIN SELECT MIN(key1) FROM s1 WHERE key1 = 'abcdefg';
26  
27  EXPLAIN SELECT MIN(key1) FROM s1 WHERE key1 = 'NlPros'; #NlPros 是 s1表中key1字段真实存在的数据
28  
29  #select * from s1 limit 10;
30  
31  #当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可以
32  #使用覆盖索引的情况下,在`Extra`列将会提示该额外信息。比方说下边这个查询中只
33  #需要用到`idx_key1`而不需要回表操作:  Using index
34  EXPLAIN SELECT key1,id FROM s1 WHERE key1 = 'a';
35  
36  
37  #有些搜索条件中虽然出现了索引列,但却不能使用到索引
38  #看课件理解索引条件下推   Using index condition
39  EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND key1 LIKE '%a';
40  
41  
42  #在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为
43  #其分配一块名叫`join buffer`的内存块来加快查询速度,也就是我们所讲的`基于块的嵌套循环算法`
44  #见课件说明          Using join buffer (hash join)
45  EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.common_field = s2.common_field;
46  
47  
48  #当我们使用左(外)连接时,如果`WHERE`子句中包含要求被驱动表的某个列等于`NULL`值的搜索条件,
49  #而且那个列又是不允许存储`NULL`值的,那么在该表的执行计划的Extra列就会提示`Not exists`额外信息
50  EXPLAIN SELECT * FROM s1 LEFT JOIN s2 ON s1.key1 = s2.key1 WHERE s2.id IS NULL;
51  
52  
53  #如果执行计划的`Extra`列出现了`Using intersect(...)`提示,说明准备使用`Intersect`索引
54  #合并的方式执行查询,括号中的`...`表示需要进行索引合并的索引名称;
55  #如果出现了`Using union(...)`提示,说明准备使用`Union`索引合并的方式执行查询;
56  #出现了`Using sort_union(...)`提示,说明准备使用`Sort-Union`索引合并的方式执行查询。
57  EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key3 = 'a';
58  
59  
60  #当我们的`LIMIT`子句的参数为`0`时,表示压根儿不打算从表中读出任何记录,将会提示该额外信息
61  EXPLAIN SELECT * FROM s1 LIMIT 0;
62  
63  
64  #有一些情况下对结果集中的记录进行排序是可以使用到索引的。
65  #比如:
66  EXPLAIN SELECT * FROM s1 ORDER BY key1 LIMIT 10;
67  
68  
69  #很多情况下排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)
70  #进行排序,MySQL把这种在内存中或者磁盘上进行排序的方式统称为文件排序(英文名:`filesort`)。
71  
72  #如果某个查询需要使用文件排序的方式执行查询,就会在执行计划的`Extra`列中显示`Using filesort`提示
73  EXPLAIN SELECT * FROM s1 ORDER BY common_field LIMIT 10;
74  
75  
76  #在许多查询的执行过程中,MySQL可能会借助临时表来完成一些功能,比如去重、排序之类的,比如我们
77  #在执行许多包含`DISTINCT`、`GROUP BY`、`UNION`等子句的查询过程中,如果不能有效利用索引来完成
78  #查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。如果查询中使用到了内部的临时表,在执行
79  #计划的`Extra`列将会显示`Using temporary`提示
80  EXPLAIN SELECT DISTINCT common_field FROM s1;
81  
82  #EXPLAIN SELECT DISTINCT key1 FROM s1;
83  
84  #同上。
85  EXPLAIN SELECT common_field, COUNT(*) AS amount FROM s1 GROUP BY common_field;
86  
87  #执行计划中出现`Using temporary`并不是一个好的征兆,因为建立与维护临时表要付出很大成本的,所以
88  #我们`最好能使用索引来替代掉使用临时表`。比如:扫描指定的索引idx_key1即可
89  EXPLAIN SELECT key1, COUNT(*) AS amount FROM s1 GROUP BY key1;
90  
91 #json格式的explain
92 EXPLAIN FORMAT=JSON SELECT * FROM s1 INNER JOIN s2 ON s1.key1 = s2.key2 
93 WHERE s1.common_field = 'a';
小结
EXPLAIN不考虑各种Cache
EXPLAIN不能显示MySQL在执行查询时所作的优化工作
EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
部分统计信息是估算的,并非精确值 

 SHOW WARNINGS;

在explain语句之后紧接着使用,可以看到被优化后的sql语句,不过只在命令行有效。

分析优化器执行计划:trace

1 SET optimizer_trace="enabled=on",end_markers_in_json=on;
2 set optimizer_trace_max_mem_size=1000000;

 

Sys schema视图

1. 主机相关:以host_summary开头,主要汇总了IO延迟的信息。
2. Innodb相关:以innodb开头,汇总了innodb buffer信息和事务等待innodb锁的信息。
3. I/o相关:以io开头,汇总了等待I/O、I/O使用量情况。
4. 内存使用情况:以memory开头,从主机、线程、事件等角度展示内存的使用情况
5. 连接与会话信息:processlist和session相关视图,总结了会话相关信息。
6. 表相关:以schema_table开头的视图,展示了表的统计信息。
7. 索引信息:统计了索引的使用情况,包含冗余索引和未使用的索引情况。
8. 语句相关:以statement开头,包含执行全表扫描、使用临时表、排序等的语句信息。
9. 用户相关:以user开头的视图,统计了用户使用的文件I/O、执行语句统计信息。
10. 等待事件相关信息:以wait开头,展示等待事件的延迟情况。

 

索引情况 
1 #1. 查询冗余索引
2 select * from sys.schema_redundant_indexes;
3 #2. 查询未使用过的索引
4 select * from sys.schema_unused_indexes;
5 #3. 查询索引的使用情况
6 select index_name,rows_selected,rows_inserted,rows_updated,rows_deleted
7 from sys.schema_index_statistics where table_schema='dbname' ;

 

表相关
1 # 1. 查询表的访问量
2 select table_schema,table_name,sum(io_read_requests+io_write_requests) as io from
3 sys.schema_table_statistics group by table_schema,table_name order by io desc;
4 # 2. 查询占用bufferpool较多的表
5 select object_schema,object_name,allocated,data
6 from sys.innodb_buffer_stats_by_table order by allocated limit 10;
7 # 3. 查看表的全表扫描情况
8 select * from sys.statements_with_full_table_scans where db='dbname';

 

语句相关
 1 #1. 监控SQL执行的频率
 2 select db,exec_count,query from sys.statement_analysis
 3 order by exec_count desc;
 4 #2. 监控使用了排序的SQL
 5 select db,exec_count,first_seen,last_seen,query
 6 from sys.statements_with_sorting limit 1;
 7 #3. 监控使用了临时表或者磁盘临时表的SQL
 8 select db,exec_count,tmp_tables,tmp_disk_tables,query
 9 from sys.statement_analysis where tmp_tables>0 or tmp_disk_tables >0
10 order by (tmp_tables+tmp_disk_tables) desc;

 

IO相关 
1 #1. 查看消耗磁盘IO的文件
2 select file,avg_read,avg_write,avg_read+avg_write as avg_io
3 from sys.io_global_by_file_by_bytes order by avg_read limit 10;
4 Innodb 相关

 

Innodb 相关 
1 #1. 行锁阻塞情况
2 select * from sys.innodb_lock_waits;

 

 

 

到了这里,关于MySQL 创建索引的原则,优化的思路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL面试题入门:四大范式、SQL生命周期、SQL六大语言、索引、最左匹配原则....

    第一范式:属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列) 第二范式:满足第一范式;且不存在部分依赖,即非主属性必须完全依赖于主属性。(主属性即主键;完全依赖是针对于联合主键的情况,非主键列不能只依赖于主键的一部分) 第三范式:

    2024年04月26日
    浏览(56)
  • mysql织梦索引优化之MySQL Order By索引优化

    在一些情况下,MySQL可以直接使用索引来满足一个ORDER BY 或GROUP BY 子句而无需做额外的排序。尽管ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的ORDER BY 字段在WHERE 子句中都被包括了。 使用索引的MySQL Order By 下列的几个查询都会

    2024年02月04日
    浏览(48)
  • Elasticsearch深入学习 (二) 索引创建及分片优化经验

    一、索引与分片的关系 ES集群中索引可能由多个分片构成,并且每个分片可以拥有多个副本。通过将一个单独的索引分为多个分片,我们可以处理不能在一个单一的服务器上面运行的大型索引。由于每个分片可以有多个副本,通过将副本分配到多个服务器,可以提高查询的负

    2024年02月15日
    浏览(42)
  • MySQL索引优化与查询优化

    MySQL中提高性能的一个最有效的方式是对数据表设计合理的索引。索引提供了访问高效数据的方法,并且加快查询的速度,因此索引对查询的速度有着至关重要的影响。 使用索引可以快速地定位表中的某条记录,从而提高数据库查询的速度,提高数据库的性能。 如果查询时没

    2024年02月05日
    浏览(50)
  • MySQL 参考文档:SQL 语句优化(SELECT 语句优化)之索引条件下推(索引下推)优化

    索引下推优化官方文档说明 (Section 8.2.1.5):https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html 1. 什么是索引下推? qquad 索引条件下推 (Index Condition Pushdown,ICP) 是 MySQL 在使用索引从表中检索行时的一种优化方法。在没有 ICP 的情况下,存储引擎遍历索引以定位基

    2024年02月16日
    浏览(43)
  • MySql索引分类及创建索引的相关语法

    1.1 InnoDB中索引的分类 聚集索引与二级索引之间的B+树的结构 sql语句索引执行的过程讲解 根据id查询的聚集索引效率要比二级索引高,故第一条sql的执行效率要高于第二条sql的执行效率。 如果一个索引只关联一个字段,这种索引称为单列索引,如果一个索引关联了多个字段,

    2024年02月16日
    浏览(41)
  • MySQL 数据存储和优化------MySQL索引原理和优化 ---- (架构---索引---事务---锁---集群---性能---分库分表---实战---运维)持续更新

    Mysql架构体系全系列文章主目录(进不去说明还没写完) https://blog.csdn.net/grd_java/article/details/123033016 本文只是整个系列笔记的第二章:MySQL索引原理和优化,只解释索引相关概念。 索引可以提高查询效率,影响where查询和order by排序,它可以从多方面进行分类,但是实际创建时

    2024年02月02日
    浏览(54)
  • MySQL优化思路及方向

    本系列为:MySQL数据库详解,为千锋资深教学老师独家创作,致力于为大家讲解清晰MySQL数据库相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【关注】持续追更~ 文末有本文重点总结,技术类问题,也欢迎大家和我们沟通交流! 从今天开始本系列

    2024年02月06日
    浏览(28)
  • mysql 查询优化 、索引失效

    查询优化 物理查询优化 通过索引和表连接方式等技术来进行优化,这里重点需要掌握索引的使用 逻辑查询优化 通过SQL 等价变换 提升查询效率,直白一点就是说,换一种查询写法执行效率可能更高 索引失效 计算、函数、类型转换(自动或手动)导致索引失效 select sql_no_c

    2024年02月10日
    浏览(49)
  • MySQL 索引优化实践(单表)

          索引是为了高效查询排好序的数据结构,当表数据量到达一个量级没有对应索引帮助查询耗时会很长,MySQL资源开销也会非常大,当然索引也不能随意创建,要做到 尽量少的索引解决尽量多的问题 ,这里会对一些业务场景做索引优化演示,这篇文中只介绍单表索引优

    2024年02月07日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包