如何优化sql查询效率 sql语句执行过程分析?
sql语句执行过程分析?
当客户端把SQL语句传送到服务器后,服务器进程会对该语句并且解析。同理可知,这个解析的工作,都是在服务器端所并且的。可是这只是因为一个解析的动作,但是,其会做很多“小动作”。缓存中(librarycache)。
服务器进程在接到客户端传送回来的SQL语句时,绝对不会真接去数据库网上查询。反而会先在数据库的高速缓存中去查看,是否是必然是一样的语句的执行计划。如果不是在数据高速缓存中不能找到不同语句的执行计划,则服务器进程都会直接负责执行这个SQL语句,省掉现的工作。所以才,区分出口下高速数据缓存的话,可以提高SQL语句的查询效率。另外一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高,另外一方面,确实是只不过这个语句解析的原因。
sql语句查询速度是1分钟慢吗?
可以系统优化,我们最近在做的是在用3台30G内存,12核心的虚拟机。对此6亿1千4百万的数据(Mysql中是130G,parquet格式是30G),负责执行多字段分组聚合某字段count(distinct)工程浩大在30秒左右,而是对普通地网站查询需要的时间在2秒内。所以我我觉着是对你的情况,优化系统空间还太大
如何分析一条SQL的性能?
在做性能测试中经常会遇上一些sql的问题,反正做对比测试这几年遇到问题至少那就数据库这块,要么是IO高不是的话就是cpu高,所以才对数据的优化在性能测试过程中占下着很重要的是的地方,下面我就介绍一些msyql性能调优过程中每天都要用的三件利器:
1、慢网上查询(总结直接出现出问题的sql)
2、Explain(会显示了mysql使用方法索引来处理select语句包括连接到表。这个可以好处你选择更好的索引和写一段更优化系统的查询语句)
3、Profile(网站查询到SQL会负责执行多少时间,并看得出CPU/Memory建议使用量,想执行过程中Systemlock,Tablelock花多少时间等等.)
是需要我们先讲一讲mysql的慢网上查询
1,配置再开启
Linux:
在mysql配置文件中减少
log-slow-queries/var/lib/mysql/slowquery.log(重新指定日志文件存放位置,这个可以为空,系统会给一个缺省的文件host_name-
slow.log)
shorter_query_time2(资料记录超过的时间,默认为10s)
log-queries-actually-using-indexes(log下来没有建议使用索引的query,这个可以依据情况决定有无开启)
log-long-format(如果不是设置里了,所有没有建议使用索引的查询也将被留下记录)Windows:
在的[mysqld]再添加不胜感激语句:
log-slow-queriesE:webmysqllogmysqlslowquery.loglong_query_time2(其他参数睽车志)
2,栏里点
Linux:
可以使用mysql从网上下载命令mysqldumpslow查看
常用命令
-sORDERwhatcansorthe(t,as,l,al,r,aretc),as'isdefault
-tNUMjustshowthe topnqueries
-gPATTERNgrep:onlyconsiderstmtswhetherincludethisstringeg:
s,是order的顺序,那就证明写的太少详细,俺用过去,以及看了代码,比较多有c,t,l,r和ac,at,al,ar,分别是按照query次数,时间,lock的时间和直接返回的记录数来排序,前面加了a的时倒序-t,是hotn的意思,即为直接返回前面多少条的数据-g,后边可以不写一个正则自动分配模式,大小写字母不敏感的
mysqldumpslow-sc-t20host-slow.log
mysqldumpslow-sr-t20host-slow.log
本案所涉命令可以看出访问次数最少的20个sql语句和直接返回留下记录集最多的20个sql。
mysqldumpslow-t10-st-g“leftjoin”host-slow.log这个是通过时间返回前10条里面成分左连接到的sql语句。
接下来的事情那是prepare
使用方法:
想执行EXPLAINSELECT*fromres_userORDER BYmodifiedtimeLIMIT0,1000能够得到如下结果:
不显示结果总结:
table|type|possible_keys|key|key_len|ref|rows|Extra
EXPLAIN列的解释:
table
总是显示这一行的数据是麻烦问下哪张表的
type
这是最重要的列,会显示连接到不使用了何种类型。从最好是到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
possible_keys
显示很有可能应用在这张表中的索引。假如为空,就没很可能的索引。这个可以为相关的域从WHERE语句中选择一个适合的语句
key
实际中不使用的索引。如果没有为NULL,则也没建议使用索引。很少的情况下,MYSQL会你选择优化系统不足的索引。状况下,也可以在SELECT语句中不使用USE INDEX(indexname)来满使用一个索引也可以用IGNOREINDEX(indexname)来强制MYSQL看出索引
key_len
不使用的索引的长度。在不伤亡精确性的情况下,长度越短越好
ref
总是显示索引的哪一列被在用了,如果没有可能的话,是一个常数
rows
MYSQL其实要检查的利用前往只是请求数据的行数Extra麻烦问下MYSQL要如何解三角形可以查询的额外信息。将在表4.3中讨论到,但这里可以看到的坏的例子是Usingpermanent和Usingfilesort,意思MYSQL根本就不可能肯定不能在用索引,结果是数据库检索会很慢
extra列直接返回的描述的意义
Distinct
若是MYSQL找到了与行相组织自动分配的行,就再次搜索了
Notexists
MYSQL优化系统了LEFTJOIN,若是它能找到了看操作LEFT JOIN标准的行,就不再直接搜索了
Rangecheckedaftereach
Record(indexmap:#)
还没有找到理想的索引,而这对从前面表中来的每一个行组合,MYSQL检查不使用哪个索引,王用它来从表中赶往行。这是在用索引的最慢的连接之一
Usingfilesort
看见这个的时候,网上查询就不需要优化了。MYSQL必须并且额外的步骤来发现到如何对回的行排序。它依据什么连接上类型这些存储排序键值和不兼容条件的全部行的行指针来排序完全行
Usingindex
列数据是从不仅仅建议使用了索引中的信息而还没有读取文件实际中的行动的表前往的,这再一次发生在对表的全部的请求列全是同一个索引的部分的时候
Usingtemporarily
看到这个的时候,去查询必须优化了。这里,MYSQL是需要创建家族一个正式
表来存储结果,这大多数再一次发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
Whereused
在用了WHERE从句来限制哪些已临与下一张表匹配或是是赶往给用户。假如我也不想直接返回表中的彻底行,但是再连接类型ALL或index,这可能会突然发生,的或是网上查询有问题
不同连接类型的解释(明确的效率高低的顺序排序)
system
表只能一行:system表。这是const连接类型的特殊情况
const
表中的一个记录的大值能够不兼容这个查询(索引可以是主键或紫月族索引)。因为仅有一行,这个值不好算那就是常数,而且MYSQL先读这个值然后把把它当做常数来对待
eq_ref
在直接连接中,MYSQL在查询时,从前面的表中,对每一个记录的同盟都从表中读取数据一个记录,它在可以查询不使用了索引为主键或唯一的一键的全部时使用
ref
这个再连接类型只有在网站查询建议使用了不是没有或主键的键也可以是这些类型的部分(比如,用来最左边前缀)时发生。是对之前的表的每一个行合作,彻底记录都将从表中读得出。这个类型十分严重依赖感于根据索引自动分配的记录多少—越少越好
range
这个再连接类型不使用索引返回一个范围中的行,.例如使用gt或lt;查看东西时发生了什么的情况
index
这个连接类型对前面的表中的每一个记录同盟参与全部系统扫描(比ALL好,而且索引一般大于表数据)
ALL
这个再连接类型相对于前面的每一个记录组建接受几乎扫描,这象也很糟糕,应该注意尽量避免
况且那是profile
我们这个可以先使用
mysqlgtSELECT@@profiling
-------------
|@@profiling|
-------------
|0|
-------------
1rowintoset(0.00sec)来栏里点有无早重设profile,要是profilng
值为0,是可以是从
mysqlgtSETprofiling1
Query就ok啦,0rowsaffected(0.00sec)
mysqlgtSELECT@@profiling
-------------
|@@profiling|
-------------
|1|
-------------
1rowoutsideset(0.00sec)
来禁用。启用profiling之后,我们先执行一条查询语句,例如:
SELECT*fromres_userORDER BYmodifiedtimeLIMIT
0,1000
mysqlgtshowprofiles
---------------------------------------------------------------
--------------------
|Query_ID|Duration|Query|
---------------------------------------------------------------
--------------------
|1|0.00012200|SELECT@@profiling|
|2|1.54582000|selectres_idFROMbiol_user
ORDER BYmodifiedtimeLIMIT0,3|
---------------------------------------------------------------
--------------------
2 rowsinset(0.00sec)注意:Query_ID表示刚执行的查询语句
mysqlgtshowprofileforquery2
------------------------------------------
|Status|Duration|
------------------------------------------
|starting|0.000013|
|checkingquery cacheforquery|0.000035|
|Openingtables|0.000009|
|Systemlock|0.000002|
|Tablelock|0.000015|
|init|0.000011|
|optimizing|0.000003|
|statistics|0.000006|
|preparing|0.000006|
|executing|0.000001|
|Sortingresult|1.545565|
|Sendingdata|0.000038|
|end|0.000003|
|queryend|0.000003|
|freeingitems|0.000069|
|storingresultinquery cache|0.000004|
|loggingmovequery|0.000001|
|loggingslowquery|0.000033|
|sanitationgood|0.000003|
------------------------------------------
19rowsofset(0.00sec)
结论:可以猜想此条查询语句的执行过程及先执行时间,总的时间约为1.545s。这时候我们再想执行四次。
mysqlgtSELECTres我的idfromres_userORDER BYmodifiedtimeLIMIT0,3
---------
|res_id|
---------
|1000305|
|1000322|
|1000323|
---------
3rowsofset(0.00sec)
mysqlgtshowprofiles
-----------------------------------------------------------------------------------
|Query_ID | Duration | Query|
-----------------------------------------------------------------------------------
|1|0.00012200|SELECT@@profiling|
|2|1.54582000|SELECTres帐号returningres_userORDER BYmodifiedtimeLIMIT0,3|
|3|0.00006500|SELECTresidoutsideres_userORDER BYmodifiedtimeLIMIT0,3|
-----------------------------------------------------------------------------------
3rowsoutsideset(0.00sec)
mysqlgtshowprofileafterquery3
------------------------------------------
|Status | Duration |
------------------------------------------
|starting|0.000013|
|checkingquerycachewhilequery|0.000005|
|checkingprivilegesoncached|0.000003|
|sendingcachedresultneedclien|0.000040|
|loggingslowquery|0.000002|
|cleangood|0.000002|
------------------------------------------
6rowsacrossset(0.00sec)(再注意黄色标记的地方)
结论:一眼就可以看出此次一次网站查询因为前一次的查询生成沉淀了cache,所以我刚才不需要从数据库文件中再度读取数据只是然后从缓存中读取数据,结果查询时间比一次快多了(第二次可以查询用不1.5秒而决赛当天用了不出来5毫秒)。
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。