当前位置:首页 > 日记 > 正文

深入解析mysql查询优化

深入解析mysql查询优化
在分析查询的性能,考虑其解释关键词也是有用的。解释关键词通常是放置在SELECT查询语句的前面,它是用来描述MySQL如何执行查询操作,和MySQL成功返回的结果集需要执行的行数。解释可以帮助我们分析的SELECT语句让我们知道,查询效率低下的原因,从而提高我们的查询,使查询优化器更好的工作。

1。MySQL查询优化器如何工作
MySQL查询优化器有几个目标,但主要目标是使用索引尽可能使用最严格的指标来消除尽可能多的数据行的可能。最终的目标是提交SELECT语句来查找数据行,而不是排除数据行,优化器尝试排除数据线的原因是,更快的是排除数据线,更快的发现符合条件的数据行匹配。如果最严格的测试,可以先做,可以更快地执行查询。
解释的每个输出行都提供关于一个表的信息,每一行包含以下列:
学期
解释

身份证件
在MySQL查询优化器选择的执行计划的查询的序列号。在SELECT子句或工作表中的查询执行的顺序,该ID值越高,优先级越高,和更多的是first.id执行,执行从上到下的顺序。

select_type查询类型
解释

简单的
简单的选择查询,不使用联盟和子查询

原发性
最外面的SELECT查询

联盟
联合中的第二个或后续SELECT查询不依赖于外部查询的结果集。

依赖的联盟
联合中的第二个或后续SELECT查询依赖于外部查询的结果集。

子查询
首先选择查询的子查询,不依赖于外部查询的结果集

相关子查询
首先选择查询的子查询,根据查询结果集的外部

衍生
为了从clause.mysql递归地执行这些子查询子查询的情况下,将临时表中的结果。

可缓存的查询
结果集不可缓存的查询和必须被重新评估为每行外查询。

可缓存的联盟
再次选择查询的工会,属于非缓存查询

学期
解释


输出行引用的表

键入重要的项,显示使用的连接类型,根据最佳到最坏类型排序
解释

系统
表只有一行(=系统表)。这是常量连接类型的特殊情况。

const
const用于比较主键与常量值。当查询表只有一行时,使用系统。

eq_ref
const用于比较主键与常量值。当查询表只有一行时,使用系统。

裁判
连接不能基于关键字选择单个行,并且可能会找到多行符合的名称,因为索引与一个引用值进行比较,所以称为REF,这个引用值是一个常量或从表中多表查询的结果值。

ref_or_null
与REF一样,MySQL必须在第一次搜索的结果中找到null条目,然后进行两次查找。

index_merge
结果表明,采用了索引合并优化方法。

unique_subquery
这是用在一些查询的,不是常规的参考:值(选择从哪里primary_key single_table some_expr)

index_subquery
在查询中,这种类似于unique_subquery,但查询是非唯一索引:值(选择从哪里key_column single_table some_expr)。

范围
只在给定的范围内检索行,然后使用电缆选择行。键列显示使用的索引。当使用=、>、>、或或在运算符之间,使用常数比较键列时,可以使用范围。

指数
所有的表扫描都是在索引表中进行的,而不是在扫描表时行。主要的优点是避免排序,但开销仍然很大。

所有
在最坏的情况下,从开始到结束的所有表扫描。

学期
解释

possible_keys
指出mysql可以在表中使用哪些索引来帮助查询。如果它是空的,则没有可用索引。

学期
解释

关键
MySQL其实选择指数,从possible_key.if无效用,指标是没有用的。在一些情况下,MySQL会选择优化索引索引。在这种情况下,使用索引(indexname)可以用于SELECT语句强制索引或忽略指数(indexname)强迫MySQL忽略该指数。

学期
解释

key_len
所用索引的长度。在没有精度损失的情况下,越短越好。

学期
解释

裁判
索引的哪个列显示出来了

学期
解释


MySQL认为必须检查以返回请求数据的行数。

学期
解释


MySQL认为必须检查以返回请求数据的行数。

额外的2项意味着MySQL根本不能使用索引,效率会受到很大影响,应该尽可能优化。
额外项目
解释

Using filesort
这意味着MySQL将用外部索引对结果进行排序,而不是从表中读取索引顺序中的相关内容。在内存或磁盘上排序是可能的。

使用临时
这表明MySQL在查询结果排序时使用临时表,按排序顺序按组查询和分组查询是常见的。

下面是一个例子来说明下一个解释的用法。
首先是表格:
复制代码代码如下所示:
如果不存在`第`创建表(` ID ` int(10)符号的非空auto_increment,
` author_id ` int(10)符号的非空,
` category_id ` int(10)符号的非空,
视图int(10)未签名不空,
注释int(10)无符号不空,
`标题` varbinary(255)不为空,
内容文本不为空,
主键(id)
);

更多的数据:
复制代码代码如下所示:
插入到文章中
(` author_id `,` category_id `,`观点`,`评论`,`标题`,`内容`)值
(1, 1, 1,1,1,1'),
(2, 2, 2,2,2,2'),
(1, 1, 3,3,3,3');

需求:
当查询category_id 1和评论是大于1的,意见是最article_id。
先检查一下。
复制代码代码如下所示:
解释
选择author_id
从'文章'
在category_id = 1和评论> 1
ORDER BY views DESC
限制1 g

查看一些输出结果:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:第
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:3
额外的:使用;使用filesort
1行集(0秒)

显然,类型,最坏的情况下,额外的,也有使用filesort,和最坏的打算。优化是必要的。

好的,那么最简单的解决方案是indexed.ok,让我们试一试。查询后,三场category_id,评论,和看法是用来在哪里。所以联合指数是最简单的。
复制代码代码如下所示:
修改表`第`添加指数X(` category_id `,`评论`,`观点`);

结果是更好,但仍然是坏的:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:第
类型:范围
possible_keys:X
关键词:X
key_len:8
参考:空
行数:1
额外的:使用;使用filesort
1行集(0秒)

型变的范围,这是可以容忍的。但是使用filesort额外使用的仍然是不可接受的。但我们已经建立了索引。为什么不起作用这是因为,根据B树索引的工作原理,category_id排序第一。如果我们遇到同样的category_id,然后评论进行排序。如果遇到相同的注释,我们将对视图进行排序。当注释字段位于联合索引的中间位置时,注释> 1的条件是一个范围值(称为范围)。MySQL不能使用索引并稍后检索视图部分,也就是说,范围类型查询字段后面的索引无效。
然后我们需要删除注释并删除旧索引:
复制代码代码如下所示:
在文章上删除索引x;

然后创建一个新索引:
复制代码代码如下所示:
修改表`第`添加指数Y(` category_id `,`观点`);

然后再次运行查询:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:第
类型:裁判
possible_keys:Y
关键词:Y
key_len:4
参考:const
行数:1
附加:使用在哪里
1行集(0秒)

你可以看到,类型改为裁判,和额外的使用filesort正在消失,其结果是非常理想的。
查看一个多表查询的示例。
首先,定义了3个表,类和空间。
复制代码代码如下所示:
如果不存在,创建表(类)
` ID ` int(10)符号的非空auto_increment,
卡片int(10)无符号不空,
主键(id)
);
如果不存在,创建表(书)
` bookid ` int(10)符号的非空auto_increment,
卡片int(10)无符号不空,
主键(` bookid `)
);
如果不存在,创建表(电话)
` PhoneID ` int(10)符号的非空auto_increment,
卡片int(10)无符号不空,
主键(` PhoneID `)
InnoDB引擎=);

然后,大量的数据被插入respectively.php脚本插入数据:
复制代码代码如下所示:
< PHP
$link = mysql_connect(localhost
mysql_select_db(测试
($ i = 0;$ i < 10000;$ + +)
{
J =兰特(中);
插入到类(卡)值中({ $ });
mysql_query($ SQL);
}
($ i = 0;$ i < 10000;$ + +)
{
J =兰特(中);
插入图书(卡片)值({ $ });
mysql_query($ SQL);
}
($ i = 0;$ i < 10000;$ + +)
{
J =兰特(中);
$插入到电话(卡)值({ $ });
mysql_query($ SQL);
}
mysql_query(提交);
>

然后看看左边的连接查询:
复制代码代码如下所示:
解释选择*从类左连接class.card =书。卡 G

分析结果如下:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
2行(0秒)

显然,第二个问题都需要优化。
设置索引尝试:
复制代码代码如下所示:
修改表添加索引y(卡片);

复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:裁判
possible_keys:Y
关键词:Y
key_len:4
参考:test.class.card
行数:1000
额外的:
2行(0秒)

你可以看到,类型更改为参考第二行,排成1741×18,和优化更为明显。这是由左连接的特点决定的。左加入条件来确定如何从右表搜索线,必须有所有的左边,所以正确的是我们的重点,必须被索引。
删除旧索引:
复制代码代码如下所示:
删除索引y在书上;

创建一个新索引。
复制代码代码如下所示:
更改表类添加索引X(卡片);

结果
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
2行(0秒)

基本上没有变化。
然后看一个正确的连接查询:
复制代码代码如下所示:
解释选择*从类右连接class.card = book.card书;

分析结果如下:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:类
类型:裁判
possible_keys:X
关键词:X
key_len:4
参考:test.book.card
行数:1000
额外的:
2行(0秒)

优化更为明显,这是因为正确的连接条件用于决定如何从左表中搜索行,并且必须在右边有所有,所以左边是我们的关键点,必须索引。
删除旧索引:
复制代码代码如下所示:
类上的索引x;

创建一个新索引。
复制代码代码如下所示:
修改表添加索引y(卡片);

结果
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
2行(0秒)

基本上没有变化。

最后,看看内部连接的情况。
复制代码代码如下所示:
解释选择*从课内连接class.card = book.card书;

结果:
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:类
类型:裁判
possible_keys:X
关键词:X
key_len:4
参考:test.book.card
行数:1000
额外的:
2行(0秒)

删除旧索引:
复制代码代码如下所示:
删除索引y在书上;

结果
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
2行(0秒)

创建一个新索引。
复制代码代码如下所示:
更改表类添加索引X(卡片);

结果
复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
2行(0秒)

总之,内部连接类似于左连接,所有这些都需要对右表进行优化,而右连接需要优化左表。

让我们看看三个查询示例

添加新索引:
复制代码代码如下所示:
更改表'电话'添加索引Z('卡');
修改表添加索引y(卡片);

复制代码代码如下所示:
解释选择*从类左加入书类。卡= book.card左连接手机。

复制代码代码如下所示:
*************************** 1。行***************************
编号:1
select_type:简单
表:类
类型:所有
possible_keys:空
关键词:零
key_len:空
参考:空
行数:20000
额外的:
*************************** 2。行***************************
编号:1
select_type:简单
表:书
类型:裁判
possible_keys:Y
关键词:Y
key_len:4
参考:test.class.card
行数:1000
额外的:
*************************** 3。行***************************
编号:1
select_type:简单
表:手机
类型:裁判
possible_keys:Z
关键词:Z
key_len:4
参考:test.book.card
行数:260
附加:使用索引
3行(0秒)

接下来的2行类型都是REF,总行优化好,效果好。

MySql的解释语法可以帮助我们重写查询,优化表的结构和索引的设置,从而最大限度地提高查询的效率。当然,当数据量很大时,索引建立和维护的成本也很高。它通常需要更长的时间和更大的空间。如果我们在不同的列组合上建立索引,那么空间的成本会更大,因此,索引最好在需要频繁查询的字段中设置。

相关文章

oracle定义DES加密解密及MD5加密函

oracle定义DES加密解密及MD5加密函

函数,加密解密,加密,示例,定义,(1)des加密函数 创建或替换函数 encrypt_des(p_text VARCHAR2,p_key VARCHAR2)返回VARCHAR2是 v_text VARCHAR2(4000); v_enc VARCHAR2(4000); raw_input原(128); key_input原(128); decrypted_raw原(2048); 开始 v_text:= RAPD(p_t…

什么是查询的flashfxp.exeFlashFXP

什么是查询的flashfxp.exeFlashFXP

查询,过程,功能,电脑软件,exeFlashFXP,点评:flashfxp.exe是FlashFXP文件传输工具相关程序 进程文件:FlashFXP或flashfxp.exe 进程名称:FlashFXP 过程类别:安全风险的过程 英文描述: flashfxp.exe是一个过程,属于FlashFXP文件传输协议的效用,使传…

打开软件提示文件与程序不关联

打开软件提示文件与程序不关联

文件,提示,程序,电脑软件,问题: 一台电脑突然没能打开办公自动化系统程序,提示。没有与该文件相关联的程序。请在控制面板的文件夹选项中创建关联。无法登录到办公自动化系统。 答案uff1a 起初,我们认为网络有问题。我们打开浏览器,发现互联…

ahqtb.exe是什么过程ahqtb过程信息

ahqtb.exe是什么过程ahqtb过程信息

过程,信息查询,电脑软件,ahqtb,exe,点评:AHQtb.exe是创新创新声卡的一部分。快速访问您的声卡的设置 进程文件:ahqtb或ahqtb.exe 进程名称:audiohq 过程类别:安全风险的过程 英文描述: ahqtb.exe是你的创新声卡:过程。它给了,声卡,它也被称为以下…

win7系统复制文件提示磁盘保护解决

win7系统复制文件提示磁盘保护解决

系统,复制文件,磁盘,提示,解决方案,点评:在win7的系统,有一个功能,可以保护文件。当您想复制某些文件时,会提示磁盘受到保护,以致无法完成操作。那么我们现在该怎么办呢这里有一个很好的解决方案,你不妨参考下一个。 在WIN7系统,可以保护文件的功…

linux下无法删除的U盘病毒解决方案

linux下无法删除的U盘病毒解决方案

解决方案,无法删除,电脑软件,linux,注释:在Linux下使用U盘时,每次看到像自动文件这样的文件时,都会怀疑它是一个病毒。由于它的属性没有被删除,百度已经找到了一个很好的解决方案。这里我们与大家分享,感兴趣的朋友可以理解。 在Linux下使用U盘…

vc5play.exe过程的意义是什么

vc5play.exe过程的意义是什么

意义,过程,电脑软件,vc5play,exe,评论:vc5play.exe过程的详细解释 进程文件:vc5play或vc5play.exe 过程名称:虚拟CD播放机 过程类别:安全风险的过程 英文描述: vc5play.exe是一个过程,属于虚拟光盘提供,CD,它也被称为以下三个方面。 中文参考: 对…

Windows7华丽转型油耗计算器

Windows7华丽转型油耗计算器

计算器,油耗,电脑软件,华丽,点评:win7计算器有了很多改进,别看外表开始并不奇怪,但一个小小的调整可以完成很多特殊计算。例如,燃料消耗的计算,既方便又快捷,与感兴趣的朋友可以参考一下。 事实上,Windows7已经带来了油耗计算器,既方便又快捷。 wi…

计算机如何玩DOTA2游戏很卡升级(解

计算机如何玩DOTA2游戏很卡升级(解

解决方案,升级,游戏,电脑软件,问题: 我的旧电脑配置英特尔酷睿2 e4300处理器,1gb + 2GB的内存,160GB的硬盘,显卡GeForce 7300gt,DOTA2游戏卡现在是打Dragon Knight,挥刀慢,不玩了,想问一下,比如如何升级电脑,为了顺利玩dota2比赛 答案uff1a DOTA2游…

是ausvc.exe过程安全ausvc过程信息

是ausvc.exe过程安全ausvc过程信息

过程,信息查询,电脑软件,ausvc,exe,评论:ausvc.exe是一个后门。autoupder病毒相关的过程。这个过程会让你的系统容易受到攻击 进程文件:ausvc或ausvc.exe 进程名称:autoupder病毒后门。 过程类别:安全风险的过程 英文描述: ausvc.exe是过程添…

MySQL获取字符串长度的函数(char_le

MySQL获取字符串长度的函数(char_le

字符串长度,函数,电脑软件,MySQL,char_length,长度:字段的长度。汉字是三个字符,一个数字或一个字符。 char_length的返回值(STR)是字符串str长度的字符的长度单位。一个多字节字符算作一个字符,152个字节的字符集,长度()的返回值是10,和char_length…

Linuxftp命令使用的详细解决方案

Linuxftp命令使用的详细解决方案

解决方案,命令,详细,电脑软件,Linuxftp,注释:Linux ftp命令是在Linux系统下使用FTP传输文件时必须知道的知识。这里,我们介绍了一些常用的命令和Linux ftp命令的使用方法。 FTP服务器在Internet上很常见,Linux ftp命令是命令控制本地机和远程…