GVKun编程网logo

SQL查询-性能优化(sql查询性能优化的方法)

16

本篇文章给大家谈谈SQL查询-性能优化,以及sql查询性能优化的方法的知识点,同时本文还将给你拓展.Net+SQLServer企业应用性能优化笔记3——SQL查询语句、MySQLLimit性能优化及分

本篇文章给大家谈谈SQL查询-性能优化,以及sql查询性能优化的方法的知识点,同时本文还将给你拓展.Net+SQL Server企业应用性能优化笔记3——SQL查询语句、MySQL Limit 性能优化及分页数据性能优化、MySQL Limit性能优化及分页数据性能优化详解、MySQL 性能优化 - 根据执行计划进行性能优化等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

SQL查询-性能优化(sql查询性能优化的方法)

SQL查询-性能优化(sql查询性能优化的方法)

我不太擅长SQL,因此我要求你们提供有关编写查询的帮助。
[SQL查询-表连接问题]https://codingdict.com/questions/208252)
我得到了答案,并且可以正常工作!它只是明显的缓慢。我讨厌这样做,但是我真的希望有人在那里推荐一些优化查询的方法。我什至没有自己尝试过,因为我对SQL不够了解,甚至无法开始使用谷歌搜索。

答案1

小编典典

可能有帮助的是在要加入的列上创建索引。例如;

CREATE INDEX name_for_index ON Main (StatusID);

它将为此列生成一个查询表,执行查询的算法将使用该表。

编辑:如果您不允许更改数据库,则可能不走运。我已经看到在某些情况下放宽JOIN语句可以改善性能,那就是这样。

...FROM  Main m, Status st, Secondary sWHERE  st.ID = m.StatusID  AND s.MainID = m.ID  AND   ( s.MainID IS NULL AND m.WhenDate = <YourDate>    OR    s.MainID IS NOT NULL AND s.WhenDate = <YourDate> )  AND TypeId = <TypeFilter>  AND ... other filters, if you need any ...

然后处理您的其他情况,其中INNER JOIN需要更加详细。

.Net+SQL Server企业应用性能优化笔记3——SQL查询语句

.Net+SQL Server企业应用性能优化笔记3——SQL查询语句

在上一篇文章中我们使用了几种方法来确定瓶颈,找到瓶颈,下面再回顾一下:

  • LoadRunner压力测试+Windows计数器,这种方法主要是找出大概的性能问题是在哪台服务器,主要是哪个资源紧张。
  • ANTS Profiler+sql Server Profiler,这两个工具的完美搭配可以准确的定位性能是出在哪个函数,哪个sql语句上。

如果性能问题是出在程序上,那么就要根据业务对程序中的函数进行调整,可能是函数中的写法有问题,算法有问题,这种调整如果不能解决问题的话,那么就要从架构上进行考虑,我们是不是应该使用这种技术,有没有替代的方案来实现同样的业务功能?举个简单的例子,假设经过跟踪发现,一个负责生成图表的函数存在性能问题,尤其是在压力测试情况下性能问题尤为严重。原来的图表生成是完全基于GDI+在Web服务器上根据数据进行复杂的绘图,然后将绘出的图片保存在磁盘上,然后在HTML中添加img标签来引用图片的地址。现在使用GDI+会消耗大量内存和cpu,而算法上也没有太大的问题,那么这种情况下我们就需要考虑修改架构,不使用GDI+ 绘图的方式,或者是使用异步绘图的方式。既然绘图会消耗大量的服务器资源,那么一种解决办法就是将绘图的操作从服务器转移到客户端。使用SilverLight技术,在用户打开网页是只是下载了一个SilverLight文件,该文件负责调用Web服务器的Web服务,将绘图所需的数据获取下来,然后在客户端绘图展现出来。这样服务器只提供WebService的数据访问接口,不需要做绘图操作。

.net上的优化我暂时不表,今天主要讲数据库的优化。使用ANTS Profiler+sql Server Profiler我们可以精确定位某个业务操作对应的数据库脚本或者存储过程。ANTS Profiler告诉我们一个方法在调用的时候花了10秒的时间,那么我们就可以使用VS打开源代码,找到该放入,然后找到对应调用的存储过程,这里也许一个方法里面调用了多个数据层方法,调用了多个存储过程。将调用的这些存储过程记下了,然后在sql Server Provider的跟踪文件里面去找调用该存储过程花费的Duration。

ANTS Provider跟踪出调用该方法的时间-SUM(所有调用的存储过程的Duration)=C#中进行逻辑处理的时间+Web服务器和数据库服务器之间网络传输数据的时间

一般企业应用或小型应用中数据库服务器和Web服务器要不是就在同一个机房,同一个局域网,或者干脆是同一台机器,这种情况下网络传输速度是很快的,所以我们不考虑网络传送上面的时间。那么就得出:

C#中进行逻辑处理的时间=ANTS Provider跟踪出调用该方法的时间-SUM(所有调用的存储过程的Duration)

代码中的时间得到了,sql Server中的时间(也就是Duration字段)得到了,那么就可以判断出打开该页面各个服务器所花费的时间,从而找到我们要优化的方向,是存储过程还是C#代码。如果是存储过程,那么通过查询sql Server Profiler中内容可以找到具体是哪一个存储过程消耗的时间最长。

“射人先射马,擒贼先擒王。”多个存储过程被调用,如果性能出在数据库服务器上,那么进行性能优化时首先要调优的是最大Duration最大的存储过程,另外还有就是Reads很大的存储过程。如果Duration很大但是Reads和Writes都不算特别大,那么有可能是以下原因:

  1. 这个存储过程相关的资源正在被其他事务占用,也就是说该存储过程被阻塞所以才花了那么多时间。这种情况只需要把该存储过程提出,多执行几次,看是不是仍然Duration很大但Reads不大。
  2. 存储过程本身很复杂,里面的T-sql语句就是五六百行,编译出的执行计划也是一堆,里面进行了大量的逻辑判断、大量函数的调用,这种情况下进行调优就比较痛苦了。实际上这次我调优的这个项目就是如此,抓取出来的存储过程尽是复杂的逻辑,少则两三百行代码,多则五六百行,里面还有大量的用户定义函数的调用。对于这种存储过程,我接下来会专门写篇博客介绍下我们这个项目是如何调优的。
  3. 程序读取的数据不多,但是需要对数据进行大量的运算。哈希联接、聚合函数、disTINCT、UNION等都是比较耗cpu的。如果是这种情况那就看能不能建立索引或者改写法进行调优。

前面说的是Duration大而Reads小的情况,当然更常见的情况是Duration和Reads都很大。那么我们就将主要精力集中在如何减小Reads上。造成Reads很多的原因大概有以下几种:

  1. 没有建立相应的索引。对表t1进行查询,条件是where c2='abc'返回c1,c2,c3三个字段,那么这种情况下如果没有对c2建立非聚集索引(c1是主键,建立了聚集索引),那么这个查询将会进行“聚集索引扫描”,本来可能只查出几条记录的,结果要把表的所有记录都扫描一篇,自然Reads就高了。解决办法就是建立相应的索引,比如这里只需要对c2字段建立非聚集索引,然后将c3字段作为包行列就行了。如果只是最c2字段建立非聚集索引,那么前面说到的查找在进行了“非聚集索引查找”后还会进行“键查找”来找到c3列的值,所以要建立的正确的索引才行。
  2. 不符合SARG原则。查询如果不符合SARG原则,那么即使建立了索引也没法使用。SARG就是查询参数的意思,具体怎么写才符合SARG,大家可以百度,已经有很多相关文章了,我就不累述。
  3. 涉及的业务数据量大。也就是说即使建立了正确的索引,查询也符合SARG使用到了该索引,但是由于涉及的数据量太大了,所以Reads仍然很大。这种情况就不能再从索引和查询入手,而只能从数据库的设计入手。是否能够增加适当的冗余字段,对数据库进行反范式化,或者如果数据的实时性要求不高的话则可以建立中间汇总表,使用sql作业来维护这个中间汇总表,查询的时候只查询该中间汇总表即可。或者是否可以建立索引视图或者计算列,然后在计算列中建立索引的方式进行一个预运算,减小实际查询时涉及的数据量。
  4. 使用了不当的视图。如果对视图的定义很复杂,涉及的表很多,在查询的时候使用了该视图,但是实际上只用到了视图中的一张或两张表,对视图的查询会造成系统根据视图定义查询其他与该查询不相关的表。所以在使用视图的时候一定要知道视图的定义,不用贪图一时的方便而随便使用视图。
  5. 不正确的使用了用户定义函数。一个存储过程中几百行代码,出于编写方便,大量的调用了一个用户定义表值函数,而该函数是进行了复杂的查询和运算才返回结果的。如果数次或者数十次的调用该用户定义表值函数,那么就会进行很多这种复杂的查询和运算,自然Reads也就很大了。解决办法是尽量减少对这种复制函数的调用,比如一次调用后就将解决保存在表变量或临时表中,接下来再使用的话就使用该表变量或临时表即可。

如果Duration并不大,但是Reads却很大的查询仍然需要需要进行优化。虽然表现出来消耗的时间并不大,但是由于Reads很多,那么说明要进行大量的IO,在高并发的情况下大量的IO处理不过来会加重磁盘的负担,造成cpu占用率上升,性能降低,这时其Duration就会变大。关于Duration不大但是Reads很大的情况仍然是前面说到的几点情况,建立相关索引、修改查询语句等便可解决。

MySQL Limit 性能优化及分页数据性能优化

MySQL Limit 性能优化及分页数据性能优化

MySQL Limit可以分段查询数据库数据,主要应用在分页上。虽然现在写的网站数据都是千条级别,一些小的的优化起的作用不大,但是开发就要做到极致,追求完美性能。下面记录一些limit性能优化方法。

Limit语法:

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT接受一个或两个数字参数。参数必须是一个整数常量。
如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)。

支持 limit # offset # 语法:

mysql> SELECT * FROM table LIMIT 5,10; //检索记录行6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为-1
mysql> SELECT * FROM table LIMIT 95,-1; //检索记录行96-last

//如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMIT n 等价于 LIMIT 0,n
mysql> SELECT * FROM table LIMIT 5; //检索前5个记录行


不同数据量读取数据效率比较:
1.offset比较小的时候:

select * from table limit 5,10

多次运行,时间保持在0.0004-0.0005之间


Select * From table Where id >=(  
Select id From table Order By id limit 10,1  
) limit 10
多次运行,时间保持在0.0005-0.0006之间。所有,在offset较小的时候,直接使用limit效率会高点!


2.offset数据比较大的时候:

select * from table limit 10000,10
多次运行,时间保持在0.0187秒左右。



Select * From table Where id >=(  
Select id From table Order By id limit 10000,1  
) limit 10
多次运行,时间保持在0.061秒左右,是前者的1/3左右。所以,offset较大时,使用后者效率会搞!这是用了id做索引的结果。


如果用id作为数据表的主键:

select id from table limit 10000,10
查询花费时间大概在0.04秒,这是因为用id主键作为索引的结果。


Limit性能优化:

Select * From cyclopedia Where ID>=(  
Select Max(ID) From (  
Select ID From cyclopedia Order By ID limit 90001  
) As tmp  
) limit 100;  
Select * From cyclopedia Where ID>=(  
Select Max(ID) From (  
Select ID From cyclopedia Order By ID limit 90000,1  
) As tmp  
) limit 100;
同样是取90000条后100条记录,第2句会快点。因为第1句是先取前90001条记录,取其中最大一个ID值作为起始标识,然后利用它快速定位下100条数据;而第2句是只取了最后一条记录,然后取ID值作为起始标识定位100条记录。第2句可简写成:
Select * From cyclopedia Where ID>=(  
Select ID From (  
Select ID From cyclopedia Order By ID limit 90000,1  
) As tmp  
) limit 100;
省去Max运算,一般ID都是递增。


分页数据性能优化:

1、对于数据量较大数据表,可以建立主键和索引字段建立索引表,通过索引表查询相应的主键,在通过主键查询数据量的数据表;

2、如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!这样能提高读取速度

3、利用in:先通过where条件取得相应的主键值,然后利用主键值查询相应的字段值。




MySQL Limit性能优化及分页数据性能优化详解

MySQL Limit性能优化及分页数据性能优化详解

MySQL Limit可以分段查询数据库数据,主要应用在分页上。虽然现在写的网站数据都是千条级别,一些小的的优化起的作用不大,但是开发就要做到极致,追求完美性能。下面记录一些limit性能优化方法。

Limit语法:

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT接受一个或两个数字参数。参数必须是一个整数常量。

如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)。

支持 limit # offset # 语法:

mysql> SELECT * FROM table LIMIT 5,10; //检索记录行6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为-1
mysql> SELECT * FROM table LIMIT 95,-1; //检索记录行96-last
//如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMIT n 等价于 LIMIT 0,n
mysql> SELECT * FROM table LIMIT 5; //检索前5个记录行

limit n,m 表示从第n条记录开始选择m条记录。而大多数开发人员喜欢使用这类语句来解决Web中经典的分页问题。对于小规模的数据,这并不会有太大的问题。对于论坛这类可能具有非常大规模数据的应用来说,limit n,m 的效率是十分低的。因为每次都需要对数据进行选取。如果只是选取前5条记录,则非常轻松和容易;但是对100万条记录,选取从80万行记录开始的5条记录,则还需要扫描记录到这个位置。

也就是说limit 10000,20意味着扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行;问题就在这里,如果是limit 100000,100,需要扫描100100行,在一个高并发的应用里,每次查询需要扫描超过10W行,性能肯定大打折扣。

不同数据量读取数据效率比较:

1.offset比较小的时候:

select * from table limit 5,10

多次运行,时间保持在0.0004-0.0005之间

Select * From table Where id >=( 
Select id From table Order By id limit 10,1 
) limit 10

多次运行,时间保持在0.0005-0.0006之间。所有,在offset较小的时候,直接使用limit效率会高点!

2.offset数据比较大的时候:

select * from table limit 10000,10

多次运行,时间保持在0.0187秒左右。

Select * From table Where id >=( 
Select id From table Order By id limit 10000,1 
) limit 10

多次运行,时间保持在0.061秒左右,是前者的1/3左右。所以,offset较大时,使用后者效率会搞!这是用了id做索引的结果。

如果用id作为数据表的主键:

select id from table limit 10000,10

查询花费时间大概在0.04秒,这是因为用id主键作为索引的结果。

Limit性能优化:

Select * From cyclopedia Where ID>=( 
Select Max(ID) From ( 
Select ID From cyclopedia Order By ID limit 90001 
) As tmp 
) limit 100; 
Select * From cyclopedia Where ID>=( 
Select Max(ID) From ( 
Select ID From cyclopedia Order By ID limit 90000,1 
) As tmp 
) limit 100;

同样是取90000条后100条记录,第2句会快点。因为第1句是先取前90001条记录,取其中最大一个ID值作为起始标识,然后利用它快速定位下100条数据;而第2句是只取了最后一条记录,然后取ID值作为起始标识定位100条记录。第2句可简写成:

Select * From cyclopedia Where ID>=( 
Select ID From ( 
Select ID From cyclopedia Order By ID limit 90000,1 
) As tmp 
) limit 100;

省去Max运算,一般ID都是递增。

分页数据性能优化:

1、对于数据量较大数据表,可以建立主键和索引字段建立索引表,通过索引表查询相应的主键,在通过主键查询数据量的数据表;

2、如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!这样能提高读取速度

3、利用in:先通过where条件取得相应的主键值,然后利用主键值查询相应的字段值。

使用游标(cursor)分页:

为让mysql达到最佳查询性能,我将分页查询改为cursor查询方式:

select * from table where id > last_id limit 20 order by reply_id ASC;

上面的last_id为本页最后一条记录的id,这样就能实现“下一页”的查询了,同理也可以实现“上一页”的查询。

cursor方式分页只适合用于有顺序的数据且不支持跳页,我们可以建立自增ID或向数据表中增加有序字段:对于数据量大的项目,跳页的作用也不大,完全可以使用筛选条件达到查找的目的。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:
  • MySQL查询优化:LIMIT 1避免全表扫描提高查询效率
  • 为什么MySQL分页用limit会越来越慢
  • mysql优化之query_cache_limit参数说明
  • 详解Mysql order by与limit混用陷阱
  • mysql分页的limit参数简单示例
  • MySQL limit分页大偏移量慢的原因及优化方案
  • Mysql排序和分页(order by&limit)及存在的坑
  • MySQL limit使用方法以及超大分页问题解决
  • mysql踩坑之limit与sum函数混合使用问题详解
  • 如何提高MySQL Limit查询性能的方法详解
  • 浅谈mysql使用limit分页优化方案的实现
  • MySQL中limit对查询语句性能的影响

MySQL 性能优化 - 根据执行计划进行性能优化

MySQL 性能优化 - 根据执行计划进行性能优化

1. 使用执行计划 explain 命令分析

在要运行的 sql 前面加上 explain 就可以得到执行计划如下表:

在 explain 后面增加限制 format = json,可以让返回的数据已 json 格式返回。

对执行计划得到的各个列的含义:

1)、id 列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id 列为 null 的就表是这是一个结果集,不需要使用它来进行查询。

2)、select_type 列常见的有:

    A:simple:表示不需要 union 操作或者不包含子查询的简单 select 查询。有连接查询时,外层的查询为 simple,且只有一个

    B:primary:一个需要 union 操作或者含有子查询的 select,位于最外层的单位查询的 select_type 即为 primary。且只有一个

    C:union:union 连接的两个 select 查询,第一个查询是 dervied 派生表,除了第一个表外,第二个以后的表 select_type 都是 union

    D:dependent union:与 union 一样,出现在 union 或 union all 语句中,但是这个查询要受到外部查询的影响

    E:union result:包含 union 的结果集,在 union 和 union all 语句中,因为它不需要参与查询,所以 id 字段为 null

    F:subquery:除了 from 字句中包含的子查询外,其他地方出现的子查询都可能是 subquery

    G:dependent subquery:与 dependent union 类似,表示这个 subquery 的查询要受到外部表查询的影响

    H:derived:from 字句中出现的子查询,也叫做派生表,其他数据库中可能叫做内联视图或嵌套 select

3)、table 显示的查询表名,如果查询使用了别名,那么这里显示的是别名,如果不涉及对数据表的操作,那么这显示为 null,如果显示为尖括号括起来的 <derived N> 就表示这个是临时表,后边的 N 就是执行计划中的 id,表示结果来自于这个查询产生。如果是尖括号括起来的 < union M,N>,与 < derived N > 类似,也是一个临时表,表示这个结果来自于 union 查询的 id 为 M,N 的结果集。

4)、type 依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL,除了 all 之外,其他的 type 都可以使用到索引,除了 index_merge 之外,其他的 type 只可以用到一个索引

    A:system:表中只有一行数据或者是空表,且只能用于 myisam 和 memory 表。如果是 Innodb 引擎表,type 列在这个情况通常都是 all 或者 index

    B:const:使用唯一索引或者主键,返回记录一定是 1 行记录的等值 where 条件时,通常 type 是 const。其他数据库也叫做唯一索引扫描

    C:eq_ref:出现在要连接多个表的查询计划中,驱动表只返回一行数据,且这行数据是第二个表的主键或者唯一索引,且必须为 not null,唯一索引和主键是多列时,只有所有的列都用作比较时才会出现 eq_ref

    D:ref:不像 eq_ref 那样要求连接顺序,也没有主键和唯一索引的要求,只要使用相等条件检索时就可能出现,常见与辅助索引的等值查找。或者多列主键、唯一索引中,使用第一个列之外的列作为等值查找也会出现,总之,返回数据不唯一的等值查找就可能出现。

    E:fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在时,mysql 不管代价,优先选择使用全文索引

    F:ref_or_null:与 ref 方法类似,只是增加了 null 值的比较。实际用的不多。

    G:unique_subquery:用于 where 中的 in 形式子查询,子查询返回不重复值唯一值

    H:index_subquery:用于 in 形式子查询使用到了辅助索引或者 in 常数列表,子查询可能返回重复值,可以使用索引将子查询去重。

    I:range:索引范围扫描,常见于使用 >,<,is null,between ,in ,like 等运算符的查询中。

    J:index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见 and ,or 的条件使用了不同的索引,官方排序这个在 ref_or_null 之后,但是实际上由于要读取所个索引,性能可能大部分时间都不如 range

    K:index:索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询。

    L:all:这个就是全表扫描数据文件,然后再在 server 层进行过滤返回符合要求的记录。

5)、possible_keys

查询可能使用到的索引都会在这里列出来

6)、key 查询真正使用到的索引,select_type 为 index_merge 时,这里可能出现两个以上的索引,其他的 select_type 这里只会出现一个。

7)、key_len 用于处理查询的索引长度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的列,这里不会计算进去。留意下这个列的值,算一下你的多列索引总长度就知道有没有使用到所有的列了。要注意,mysql 的 ICP 特性使用到的索引不会计入其中。另外 key_len 只计算 where 条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到 key_len 中。

8)、ref 如果是使用的常数等值查询,这里会显示 const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为 func

9)、rows 这里是执行计划中估算的扫描行数,不是精确值

10)、extra 这个列可以显示的信息非常多,有几十种,常用的有

    A:distinct:在 select 部分使用了 distinc 关键字

    B:no tables used:不带 from 子句的查询或者 From dual 查询

    C:使用 not in () 形式子查询或 not exists 运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。

    D:using filesort:排序时无法使用到索引时,就会出现这个。常见于 order by 和 group by 语句中

    E:using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。

    F:using join buffer(block nested loop),using join buffer(batched key accss):5.6.x 之后的版本优化关联查询的 BNL,BKA 特性。主要是减少内表的循环数量以及比较顺序地扫描查询。

    G:using sort_union,using_union,using intersect,using sort_intersection:

using intersect:表示使用 and 连接各个索引的条件时,该信息表示是从处理结果获取交集

using union:表示使用 or 连接各个使用索引的条件时,该信息表示从处理结果获取并集

using sort_union 和 using sort_intersection:与前面两个对应的类似,只是他们是出现在用 and 和 or 查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。

    H:using temporary:表示使用了临时表存储中间结果。临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看 status 变量,used_tmp_table,used_tmp_disk_table 才能看出来。

    I:using where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在 server 层进行过滤。查询条件中分为限制条件和检查条件,5.6 之前,存储引擎只能根据限制条件扫描数据并返回,然后 server 层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x 之后支持 ICP 特性,可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量。extra 列显示 using index condition

    J:firstmatch (tb_name):5.6.x 开始引入的优化子查询的新特性之一,常见于 where 子句含有 in () 类型的子查询。如果内表的数据量比较大,就可能出现这个

    K:loosescan (m..n):5.6.x 之后引入的优化子查询的新特性之一,在 in () 类型的子查询中,子查询返回的可能有重复记录时,就可能出现这个

除了这些之外,还有很多查询数据字典库,执行计划过程中就发现不可能存在结果的一些提示信息

11)、filtered 使用 explain extended 时会出现这个列,5.7 之后的版本默认就有这个字段,不需要使用 explain extended 了。这个字段表示存储引擎返回的数据在 server 层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。

2. 使用 show profile 命令分析

最后,在 mysql 的每个版本中都会对执行计划进行改进,所以执行计划也不是一成不变的。在具体进行 sql 优化查询执行计划的时候,还要考虑版本的问题。

参考的文章:

show profile 命令分析:http://www.cnblogs.com/SQL888/p/5750123.html

关于SQL查询-性能优化sql查询性能优化的方法的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于.Net+SQL Server企业应用性能优化笔记3——SQL查询语句、MySQL Limit 性能优化及分页数据性能优化、MySQL Limit性能优化及分页数据性能优化详解、MySQL 性能优化 - 根据执行计划进行性能优化等相关内容,可以在本站寻找。

本文标签: