一、序言
作为程序员,难免要和数据库打交道,一般情况下,我们不是DBA ,但是又要写很多SQL,因此SQL效率就成了很大的问题。关于SQL效率优化,除了要掌握一定优化技巧外, 还得有很多经验的积累,但是这里我们可以通过执行计划对SQL进行分析,能快速找到优化的地方,这是一种很不错的方式,介绍给大家,大部分我是翻译而来,原文地址:http://dev.mysql.com/doc/refman/5.6/en/explain-output.html
二、执行计划输出列的含义:
id |
The SELECT identifier |
select_type |
The SELECT type |
table |
The table for the output row |
partitions |
The matching partitions |
type |
The join type |
possible_keys |
The possible indexes to choose |
key |
The index actually chosen |
key_len |
The length of the chosen key |
ref |
The columns compared to the index |
rows |
Estimate of rows to be examined |
filtered |
Percentage of rows filtered by table condition |
Extra |
Additional information |
● id
:
查询的标识,表示在select 执行语句中的顺序(PS:数字越大,优先执行)。如果这行是和其他行合并的结果,这个值可以为null。比如:使用 UNION 关键字,将多个select 的结果合并到一起。
● select_type
:每个select 的类型。
SIMPLE |
简单的 SELECT (没有 使用UNION 或者 子查询(PS:单表查询)) |
PRIMARY |
最外层的Select 作为primary 查询。(PS:含有子查询的情况,但是并不复杂) |
UNION |
从第二个或者在union 之后的select 作为 union 查询
|
DEPENDENT UNION |
从第二个或者在union 之后的select 作为 union 查询, 依赖于外部查询 |
UNION RESULT |
结果集是通过union 而来的,作为... |
SUBQUERY |
第一个查询是子查询 |
DEPENDENT SUBQUERY |
第一个查询是子查询,依赖于外部查询 |
DERIVED |
在from 查询语句中的(派生,嵌套很多)子查询.(PS:递归操作这些子查询) |
MATERIALIZED |
(雾化) 子查询(PS:子查询是个视图?) |
UNCACHEABLE SUBQUERY |
子查询结果不能被缓存, 而且必须重写(分析)外部查询的每一行 |
UNCACHEABLE UNION |
第二个 或者 在UNION 查询之后的select ,属于不可缓存的查询 |
● Table
:输出所用到的表(PS:通过id 联系)
● Type
:连接类型,很重要的分析手段,下面按最优到最差排序:
System:表只有一行(=系统表),const 的特例
const:表查询结果最多只有一行,因为只有一行,该查询优化部分一般是常数。比如根据主键id=1 查询。
比如:
SELECT * FROM tbl_name WHERE primary_key=1;
eq_ref:从当前这个表读出的一行,和前面所有表的行进行组合,这是除了const 和system 外,最好的连接类型,它是用于所有的都是用唯一索引去连接被主键或者不为空的索引。常用=操作符比较索引
比如:
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
ref:用于连接非唯一索引的扫描。可以对索引的列使用> = <> 的操作符。
比如:
SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROMref_table
,other_table
WHEREref_table
.key_column_part1
=other_table
.column
ANDref_table
.key_column_part2
=1;
fulltext : 该方式使用的是全文检索
ref or null : 该连接方式像ref,但是包含null 的值 ,该连接类型主要是解决子查询
比如:
SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
index_merge:索引合并优化(PS:多个索引条件情况,进行条件的合并优化)
我版本低,没出现。。,可以参考下面解释: http://dev.mysql.com/doc/refman/5.6/en/index-merge-optimization.html SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20; SELECT * FROM tbl_name WHERE (key1 = 10 OR key2 = 20) AND non_key=30; SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col; SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);
unique_subquery:这个参照ref,处理子查询
比如:
value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery:这个和unique_subquery 类似,取代非唯一索引的子查询
比如:
value IN (SELECT key_column FROM single_table WHERE some_expr)
range:只有在range 范围内的都被检索,只用索引才查询哪些行。后面Key 表示你用的那个索引:
比如:
SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name WHERE key_column IN (10,20,30); SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
index :这索引连接类型和ALL一样,除了树的索引扫描,分为两种情况: 1.会便利索引树,2.没有索引树,就是ALL 一样。
All:全表扫描,通常是最差的一种查询。
● Extra
:包含mysql 解析查询的额外信息。
Distinct:mysql 查询不同的行,当找到和当前行匹配的时候,就不再搜索了。
FirstMatch(tbl_name) :The semi-join FirstMatch join shortcutting strategy is used for tbl_name
.
Full scan on NULL key:查询分析器无法使用当前索引的一个失败策略。
Impossible HAVING: where 条件总是false,无法筛选任何行
Impossible WHERE noticed after reading const tables:和上面类似
LooseScan:利用索引来扫描一个子查询表可以从每个子查询的值群组中选出一个单一的值。
Not exists:mysql 优化了left join 的查询,
比如:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL; 假设t2.id 定义为 not null,这种情况下,Mysql 扫描t1 并且用t1.id 在t2中查找行,如果Mysql 在t2中找到匹配的行,它表明t2.id 不可能为null,因此不会扫描剩下的具有相同id的行,换句话说,t1 中的每一行,mysql 每次都在t2中做一下查询,无论t2 有多少匹配。
Using filesort:无法利用索引完成的排序,比如文件排序
Using index:利用索引树扫描得出结果,不用全部扫描
Using temporary:利用临时表存储结果集,通常查询包含 GROUP BY
and ORDER BY
。
Using where:使用where 限定那些行于下一张表匹配,或者返回到客户端,除非你想要获取or 检查表中所有行,如果extra 的值不是Using where并且连接类型不是all 或者index ,那么你可能有一些错误在你的查询中。
Using join buffer:
Using MRR:有点复杂,
参考:http://dev.mysql.com/doc/refman/5.6/en/mrr-optimization.html
和:http://blog.csdn.net/zbszhangbosen/article/details/7463394
● Key
:key 这一列表明实际你用的是那一个索引,没有则是null
● Key len
:该列是Mysql 使用key 的长度,没有则为null,文档提示这值能确定你 multiple-part key 中使用的是哪一部分。
● Rows
:表示Mysql 执行语句扫描的行数
● Possible_keys
:表示mysql 找到的这些行数据,在indexes(很多索引)里面的哪一个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。如果是空的,没有相关的索引。这时要提高性能,可通过检验WHERE子句,看是否引用某些字段,或者检查字段不是适合索引。
小结:
1.这个不得不吐槽,翻译太烂了...以至于后面都是自己的理解弄的,建议都去看原文啊,而且5.6+ 变化挺多,有些变化我也没遇到过,请见谅啊。
2.这些简单的说明呢,仅仅是给大家提供一种分析SQL 的途径,也提醒大家不要盲目的根据SQL 去判断效率,当然你经验丰富,就不说啦~。~新手学习。
3.如果你需要更详细的可以用show profile 的东西,能看到更详细的信息,精确度也更高,还有关于一些实战方面的应用,没来得及总结,这个以后再介绍吧。
4.还是请见谅下,不正确的 狗血的地方请指出哦,谢谢啦。
最后分享个不错的mysql 地址:
http://www.mysqlab.net/
http://www.mysqlpub.com/
相关推荐
在本例中,该JAR文件包含了实现JDBC驱动所需的类和资源,使得Java程序能够连接到MySQL数据库,执行SQL查询,操作数据等。 MySQL Connector/J的工作原理: 1. **连接建立**:当Java应用程序需要访问MySQL数据库时,...
本文将详细介绍MySQL 8.0.20的安装过程,该版本适用于Linux发行版中的EL7(Enterprise Linux 7,如CentOS 7)。提供的压缩包文件名为`mysql-8.0.20-el7-x86_64.tar.gz`,这是一个针对64位系统的tar归档文件,包含了...
在开发Java应用时,如果你需要连接到MySQL数据库执行SQL查询、更新数据或者管理数据库,那么你需要在项目中引入这个JAR文件。你可以通过Maven或Gradle等构建工具添加依赖,或者直接将jar文件复制到项目的类路径下。...
这个驱动程序符合JDBC接口规范,使得Java开发者可以使用标准的JDBC API来与MySQL进行交互,包括创建数据库连接、执行SQL查询和更新、管理事务等。 `mysql-connector-java-5.1.27.jar`中的主要知识点包括: 1. **...
1. `mysql-connector-java-5.1.37.jar`:这是主驱动文件,包含了所有必要的类和方法,使得Java应用程序能够与MySQL数据库建立连接,执行SQL语句,并处理结果。例如,使用`DriverManager.getConnection()`方法创建...
`mysql-connector-java-8.0.20.jar`是MySQL Connector/J的特定版本,它实现了这些JDBC接口,使得Java开发者可以方便地在代码中执行SQL查询、操作数据以及管理数据库连接。 在MySQL 8.0版本中,引入了许多新特性、...
它是MySQL开发团队推出的一个多模式JavaScript接口,支持SQL、JavaScript和Python语言,旨在提供一个统一的平台来执行数据库管理和开发任务。在MySQL Shell 8.4.0版本中,主要针对Windows x86-64位操作系统进行了...
`mysql-connector-java-5.1.25.jar`是这个驱动程序的二进制文件,包含了Java类和其他资源,用于连接到MySQL服务器并执行SQL查询。这个特定的版本兼容性广泛,适用于许多基于Java的应用场景。当下载并将其添加到项目...
这个驱动包包含所有必要的类和库,使得Java开发者可以编写代码连接并操作MySQL数据库,执行SQL语句,处理结果集等。 4. **JDBC**:Java Database Connectivity是Java平台的标准,提供了一种规范化的接口,让Java...
本文将详细介绍`mysql-connector-java`的相关知识点,以及压缩包中包含的各个版本的用途。 首先,`mysql-connector-java`是一个实现了JDBC(Java Database Connectivity)规范的驱动程序,它允许Java应用通过JDBC ...
这个驱动包允许Java程序通过JDBC(Java Database Connectivity)接口连接到MySQL服务器,执行SQL查询、事务处理等数据库操作。 `mysql-connector-java-5.1.27.jar`是该驱动包的核心文件,包含了所有必要的类和资源...
适用于:Ubuntu 24.04的...执行以下命令: apt --fix-broken install dpkg-dev dpkg -i mysql-connector-odbc_8.4.0-1ubuntu24.04_amd64.deb dpkg -i mysql-community-client-plugins_8.0.37-1ubuntu24.04_amd64.deb
5. **性能优化**:通过优化网络通信和查询执行,提高与MySQL服务器交互的效率。 6. **错误处理**:提供了详细的错误和异常处理机制,帮助开发者快速定位和解决问题。 “mysql-connector-java-8.0.22.jar.txt”可能...
它允许Java应用程序通过JDBC API与MySQL数据库进行通信,执行SQL查询、事务处理、数据插入、更新和删除等操作。MySQL Connector/J实现了JDBC接口,使得Java开发者可以使用标准的JDBC API来操作MySQL数据库,无需了解...
5. **改进的查询优化器**:MySQL 8.3.0可能有更智能的查询优化器,能做出更好的执行计划选择,提高查询速度。 6. **分区表改进**:分区表是大型数据库中常见的优化手段,新的版本可能扩展了分区策略,提升了处理大...
MySQL是世界上最受欢迎的关系型数据库管理系统之一,而`mysql-connector-java`则是MySQL官方提供的Java数据库连接器,用于在Java应用程序中与MySQL服务器进行通信。在这个话题中,我们将深入探讨`mysql-connector-...
MySQL Connector/J 8.0.23 是MySQL数据库与Java应用程序之间的重要桥梁,它是一个用于连接Java应用程序到MySQL服务器的JDBC驱动程序。这个jar文件是MySQL官方提供的,确保了与MySQL数据库的高效且可靠的通信。在Java...
MySQL for Visual Studio 是一个插件,它允许开发人员在Visual Studio环境中直接管理MySQL数据库,进行数据操作、设计表结构、编写SQL查询以及执行其他数据库相关的任务。版本1.2.7提供了与Visual Studio的紧密集成...
MySQL-server是MySQL的核心服务组件,负责处理来自客户端的请求,执行SQL语句,并管理数据库的存储和事务处理。5.6.29版本引入了InnoDB存储引擎的改进,如更好的行锁定机制,更高效的全文索引,以及对并行复制的支持...
MySQL Connector/J是MySQL数据库系统与Java应用程序之间的重要桥梁,它是一个实现了JDBC(Java Database Connectivity)规范的驱动程序,使得Java开发者能够通过编写Java代码来访问和操作MySQL数据库。"mysql-...