mysql的sql执⾏计划详解(⾮常有⽤)
引⾔:
如何建立数据库引擎查询sql实际项⽬开发中,由于我们不知道实际查询的时候数据库⾥发⽣了什么事情,数据库软件是怎样扫描表、怎样使⽤索引的,因此,我们能感知到的就只有
sql语句运⾏的时间,在数据规模不⼤时,查询是瞬间的,因此,在写sql语句的时候就很少考虑到性能的问题。但是当数据规模增⼤,如千万、亿的时候,我们运
⾏同样的sql语句时却发现迟迟没有结果,这个时候才知道数据规模已经限制了我们查询的速度。所以,查询优化和索引也就显得很重要了。
问题:
当我们在查询前能否预先估计查询究竟要涉及多少⾏、使⽤哪些索引、运⾏时间呢?答案是能的,mysql提供了相应的功能和语法来实现该功能。
分析:
MySql提供了EXPLAIN语法⽤来进⾏查询分析,在SQL语句前加⼀个"EXPLAIN"即可。⽐如我们要分析如下SQL语句:
explain select * from table where table.id = 1
运⾏上⾯的sql语句后你会看到,下⾯的表头信息:
table | type | possible_keys | key | key_len | ref | rows | Extra
EXPLAIN列的解释
table
显⽰这⼀⾏的数据是关于哪张表的
sculpture是什么意思英语type
这是重要的列,显⽰连接使⽤了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALLmysql面试题sql
说明:不同连接类型的解释(按照效率⾼低的顺序排序)
system:表只有⼀⾏:system表。这是const连接类型的特殊情况。
const :表中的⼀个记录的最⼤值能够匹配这个查询(索引可以是主键或惟⼀索引)。因为只有⼀⾏,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待。
eq_ref:在连接中,MYSQL在查询时,从前⾯的表中,对每⼀个记录的联合都从表中读取⼀个记录,它在查询使⽤了索引为主键或惟⼀键的全部时使⽤。
ref:这个连接类型只有在查询使⽤了不是惟⼀或主键的键或者是这些类型的部分(⽐如,利⽤最左边前缀)时发⽣。对于之前的表的每⼀个⾏联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好。
range:这个连接类型使⽤索引返回⼀个范围中的⾏,⽐如使⽤>或<;查东西时发⽣的情况。
热波炉index:这个连接类型对前⾯的表中的每⼀个记录联合进⾏完全扫描(⽐ALL更好,因为索引⼀般⼩于表数据)。
ALL:这个连接类型对于前⾯的每⼀个记录联合进⾏完全扫描,这⼀般⽐较糟糕,应该尽量避免。
possible_keys
显⽰可能应⽤在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择⼀个合适的语句
key
leaflet是什么实际使⽤的索引。如果为NULL,则没有使⽤索引。很少的情况下,MYSQL会选择优化不⾜的索引。这种情况下,可以在SELECT语句中使⽤USE INDEX(indexname)来强制使⽤⼀个索引或者⽤IGNORE INDEX(indexname)来强制MYSQL忽略索引
key_len
使⽤的索引的长度。在不损失精确性的情况下,长度越短越好
ref
显⽰索引的哪⼀列被使⽤了,如果可能的话,是⼀个常数
rows
MYSQL认为必须检查的⽤来返回请求数据的⾏数
Extra
关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这⾥可以看到的坏的例⼦是Using temporary和Using filesort,意思MYSQL根本不能使⽤索引,结果是检索会很慢
说明:extra列返回的描述的意义
Distinct :⼀旦mysql到了与⾏相联合匹配的⾏,就不再搜索了。
Not exists :mysql优化了LEFT JOIN,⼀旦它到了匹配LEFT JOIN标准的⾏,就不再搜索了。
对勾函数的定义
Range checked for each Record(index map:#):没有到理想的索引,因此对从前⾯表中来的每⼀个⾏组合,mysql检查使⽤哪个索引,并⽤它来从表中返回⾏。这是使⽤索引的最慢的连接之⼀。
Using filesort :看到这个的时候,查询就需要优化了。mysql需要进⾏额外的步骤来发现如何对返回的⾏排序。它根据连接类型以及存储排序键值和匹配条件的全部⾏的⾏指针来排序全部⾏。
Using index :列数据是从仅仅使⽤了索引中的信息⽽没有读取实际的⾏动的表返回的,这发⽣在对表的全部的请求列都是同⼀个索引的部分的时候。
Using temporary :看到这个的时候,查询需要优化了。这⾥,mysql需要创建⼀个临时表来存储结果,这通常发⽣在对不同的列集进⾏ORDER BY上,⽽不是GROUP BY上。
Where used :使⽤了WHERE从句来限制哪些⾏将与下⼀张表匹配或者是返回给⽤户。如果不想返回表中的全部⾏,并且连接类型ALL或index,这就会发⽣,或者是查询有问题。
因此,弄明⽩了explain语法返回的每⼀项结果,我们就能知道查询⼤致的运⾏时间了,如果查询⾥没有⽤到索引、或者需要扫描的⾏过多,那么可以感到明显的延迟。因此需要改变查询⽅式或者新建索引。mysql中的explain语法可以帮助我们改写查询,优化表的结构和索引的设置,从⽽最⼤地提⾼查询效率。当然,在⼤规模数据量时,索引的建⽴和维护的代价也是很⾼的,往往需要较长的时间和较⼤的空间,如果在不同的列组合上建⽴索引,空间的开销会更⼤。因此索引最好设置在需要经常查询的字段中。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。