促使这次探索的初衷还是因为要对一个定时脚本性能进行优化。

脚本有两个指定状态分别是status, latest_process_status,和一个超期时间expire_time进行限制。

按照我以前的习惯,直接给这一组字段建了一个联合索引。写成了 expire_time_status_latest_process_status (expire_time, status, latest_process_status)

以前只知道,联合索引的第一个值会做单独的索引,但是不知道先后顺序不同也会导致索引检查的顺序不同。

建完之后想来查看一下语句究竟会按照何种套路执行,去搜了一下如何分析,看到了执行计划。使用了之后发现大概能知道有没有用索引,有哪些备选索引,需要怎么扫描之类。 先来看个例子。

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ec_customer_service
partitions: NULL
type: range
possible_keys: expire_time_latest_process_status_status
key: expire_time_latest_process_status_status
key_len: 6
ref: NULL
rows: 95172
filtered: 25.00
Extra: Using index condition

select_type: 查询的类型,这歌例子里面是一个简单查询的列子,对应的还有复杂查询,拥有自查询的复杂查询会显示不止一列。

table: 预计会操作的表

type: 表示mysql 执行计划预测会如何去访问表中的数据,这列有all, index, ref, const range, eq_ref, null 这7种。在这里显示的ref代表的是索引扫描,而且会与某些值进行参照。经常见到的type还有 all 和 range,一个代表全表扫描,一个代表范围查找,范围查找一边会用到><=类似这种范围型的条件。

possible_keys: 可能会选择的索引,如果有多个索引可用,这里会全部列出来。

key: 执行计划会使用的索引。

key_len: 索引长度。

ref: 这个我没太明白。。应该是参照key有个什么关系。

rows: 预计会扫描多少行。

Extra: 特别需要提到的信息:

这一列包含的是不适合在其他列显示的额外信息。mysql用户手册里记录了大多数可以在这里出现的值。
常见的最重要的值如下。
“Using index”
    此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
“Using where”
    这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
“Using temporary”
    这意味着mysql在对查询结果排序时会使用一个临时表。
“Using filesort”
    这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
“Range checked for each record(index map: N)”
    这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。

上面提到了一个索引覆盖,这里说下,索引覆盖无需访问数据文件,直接读取索引文件进行返回。速度快的飞起,这一点可以从查找行数rows字段看出来。

通过上面的例子我们可以看出来,这里我需要用到的信息是行数rows和key 看一下是用到了哪个索引,并且同时看下执行需要扫描多少行才可以。说一下,这里数据一共是20w行,可以看到在使用这个索引的情况下竟然执行计划要扫描近10w行数据,可见效率是不高的。

为什么我在建立了看似不错的联合索引,效率才这么低。分析上面的sql语句不难发现,其实索引起最大作用的不应该是expire_time这个只规划了一个范围的字段,而是在status和latest_process_status上面,特别是status状态,在判断了多个状态的情况,是非常消耗查询时间的。我们不妨使用status做一个单索引来看一下开销

mysql> explain select * from ec_customer_service where expire_time<'2017-01-11' and status=1 and latest_process_status in (1000, 1001, 1002, 1003, 1004,1005);
+----+-------------+---------------------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+------+---------------+--------+---------+-------+------+-------------+
| 1 | SIMPLE | ec_customer_service | ref | status | status | 4 | const | 1003 | Using where |
+----+-------------+---------------------+------+---------------+--------+---------+-------+------+-------------+

不难发现,居然只需要 扫描1003行就可以解决问题?快了近90倍。。 可见索引并不是把要查询的字段都包含进去就可以了这么简单,而是要更详细的分析自己使用的语句到底哪个字段或者哪几个字段做成目录可以提升查询效率。

如果我们同时建立好几个相关字段索引,在查看执行计划的时候,在possible_keys字段可以看到这些相关索引被罗列出来。 我们还可以通过在where前使用 「force index (索引字段)」 来强制语句使用该索引,因为mysql语句在执行的时候,引擎并不总是会做出最优判断,你可以自己通过调整和查看执行计划,或者别的参数设置再结合自己的经验强制使用某个字段做搜索索引,从而提升搜索速度。

在这个例子中,我也尝试建立了类似 status_latest_process_status_expire_time这种联合索引,效果其实和status差不多,同样需要扫描近1000个字段,提升不大。而且filtered字段的值还会提升到达接近50%,key_lenth字段也变得很长,因为数据量并非 特别大,我还没有测试出filtered字段增大对性能带来的影响,但是如果能使用一个或两个索引字段就能搞定的事情,为什么要使用多个呢?

Reference:

http://blog.itpub.net/29773961/viewspace-1767044/   MySQL 执行计划explain详解

索引使用,分析初探。(explain分析执行计划,以及强制使用force index)的更多相关文章

  1. SQL优化 MySQL版 -分析explain SQL执行计划与笛卡尔积

    SQL优化 MySQL版 -分析explain SQL执行计划 作者 Stanley 罗昊 [转载请注明出处和署名,谢谢!] 首先我们先创建一个数据库,数据库中分别写三张表来存储数据; course: ...

  2. SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)

    本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. ...

  3. MySQL 使用explain查看执行计划

    使用explain查看执行计划, 下面是针对这两条语句进行分析,其查询结果是一样的. EXPLAIN select n.id,n.title from info n inner join info_t ...

  4. 引用:初探Sql Server 执行计划及Sql查询优化

    原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想 ...

  5. hive高阶1--sql和hive语句执行顺序、explain查看执行计划、group by生成MR

    hive语句执行顺序 msyql语句执行顺序 代码写的顺序: select ... from... where.... group by... having... order by.. 或者 from ...

  6. PostgreSQL执行计划:Bitmap scan VS index only scan

    之前了解过postgresql的Bitmap scan,只是粗略地了解到是通过标记数据页面来实现数据检索的,执行计划中的的Bitmap scan一些细节并不十分清楚.这里借助一个执行计划来分析bitm ...

  7. SQL优化 MySQL版 -分析explain SQL执行计划与Extra

    Extra 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:此文章必须有一定的Mysql基础,或观看执行计划入门篇传送门: https:.html 终于总结到哦SQK执行计划的最 ...

  8. 详解GaussDB(DWS) explain分布式执行计划

    摘要:本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点. 前言 执行计划(又称解释计划)是数据库执行SQL语句的具体步骤,例如通过索引还是全表扫描访问表中的 ...

  9. MySQL执行计划extra中的using index 和 using where using index 的区别

    本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

随机推荐

  1. day03-课堂笔记-大纲

    字典: # 字典循环: dic.keys() | dic.values() | dic.items()for k, v in dic.items():    print(k, v)        # ...

  2. MacOS 10.12 Sierra 安全性与隐私没有任何来源选项解决方法

    MacOS 10.12 Sierra 安全性与隐私没有任何来源选项解决方法 来源: 时间:2016年09月21日 在升级了macOS Sierra (10.12)版本后在“安全性与隐私”中不再有“任何 ...

  3. P2360 地下城主(BFS)

    感觉这道题还是蛮简单的,不过使使用了4个队列(其实只是一个)emmmmm,还是很好的 #include<iostream> #include<string> #include& ...

  4. P2256 一中校运会之百米跑(map+并查集)

    思路:首先处理名字,让字符串直接映射唯一一个数字,这就用map<string, int>即可. 然后,直接用并查集 #include<iostream> #include< ...

  5. [教程]教你如何制作彩色的3D打印Groot

    http://mc.dfrobot.com.cn/forum.php?mod=viewthread&tid=24916 准备工作: <ignore_js_op>  3D打印高精度G ...

  6. 环境部署(四):Linux下查看JDK安装路径

    在安装好Git.JDK和jenkins之后,就需要在jenkins中进行对应的设置,比如在全局工具配置模块,需要写入JDK的安装路径. 这篇博客,介绍几种常见的在Linux中查看JDK路径的方法... ...

  7. Linux中断管理 (3)workqueue工作队列

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

  8. c# 打印 主板信息CPU信息

    Win32_Processor CPU 参数说明: AddressWidth --在32位操作系统,该值是32,在64位操作系统是64.Architecture --所使用的平台的处理器架构.Asse ...

  9. 【转】MySQL中的行级锁,表级锁,页级锁

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引 ...

  10. 2018年JavaScript现状报告

    前言 JavaScript(后面统称JS)在过去五年得到飞速地增长,早期JS实现类似微博的“点赞”这样的功能都需要刷新一次页面. 后来开发者通过JS来制作SPA(单页面应用程序),在浏览器加载一次,后 ...