性能优化慢查询分析优化索引和配置_第1页
性能优化慢查询分析优化索引和配置_第2页
性能优化慢查询分析优化索引和配置_第3页
性能优化慢查询分析优化索引和配置_第4页
性能优化慢查询分析优化索引和配置_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、mysql性能优化-慢查询分析、优化索引和配置目录一、优化概述二、查询与索引优化分析1性能瓶颈定位Show命令慢查询日志explain分析查询profiling分析查询 2索引及查询优化三、配置优化1)      max_connections2)      back_log3)      interactive_timeout4)      key_buffer_size5)      query_cache_size6)  

2、;    record_buffer_size7)      read_rnd_buffer_size8)      sort_buffer_size9)      join_buffer_size10)    table_cache11)    max_heap_table_size12)    tmp_table_size13)    thread_cache_size14)    

3、thread_concurrency15)    wait_timeout 一、 优化概述MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候。磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的时候那么平瓶颈就会出现在网络上,我们可以用mpstat, iostat, sar和vmstat来查看系统的性能状态。除了服务器硬件的性能瓶颈,对于MySQL系统本身,我们可以使用工具来优化数据库的性能,通常有三种:使用索引,使用EXPLAIN分析查询以及调整M

4、ySQL的内部配置。二、查询与索引优化分析在优化MySQL时,通常需要对数据库进行分析,常见的分析手段有慢查询日志,EXPLAIN 分析查询,profiling分析以及show命令查询系统状态及系统变量,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。1 性能瓶颈定位Show命令我们可以通过show命令查看MySQL状态及变量,找到系统的瓶颈:Mysql> show status 显示状态信息(扩展show status like XXX)Mysql> show variables 显示系统变量(扩展show variables like XXX)Mysql>

5、; show innodb status 显示InnoDB存储引擎的状态Mysql> show processlist 查看当前SQL执行,包括执行状态、是否锁表等Shell> mysqladmin variables -u username -p password显示系统变量Shell> mysqladmin extended-status -u username -p password显示状态信息查看状态变量及帮助:Shell> mysqld verbose help |more #逐行显示 比较全的Show命令的使用可参考: 慢查询日志慢查询日志开启:在

6、配置文件f或my.ini中在mysqld一行下面加入两个配置参数log-slow-queries=/data/mysqldata/slow-query.log           long_query_time=2                       

7、                                          注:log-slow-queries参数为慢查询日志存放的位置,一般这个目录要有mysql的运行帐号的可写

8、权限,一般都将这个目录设置为mysql的数据存放目录;long_query_time=2中的2表示查询超过两秒才记录;在f或者my.ini中添加log-queries-not-using-indexes参数,表示记录下没有使用索引的查询。log-slow-queries=/data/mysqldata/slow-query.log           long_query_time=10        &#

9、160;                                                 &#

10、160;    log-queries-not-using-indexes                                        

11、60;    慢查询日志开启方法二:我们可以通过命令行设置变量来即时启动慢日志查询。由下图可知慢日志没有打开,slow_launch_time=# 表示如果建立线程花费了比这个值更长的时间,slow_launch_threads 计数器将增加设置慢日志开启MySQL后可以查询long_query_time 的值 。 为了方便测试,可以将修改慢查询时间为5秒。慢查询分析mysqldumpslow我们可以通过打开log文件查看得知哪些SQL执行效率低下rootlocalhost mysql# more slow-que

12、ry.log                            # Time: 081026 19:46:34                  

13、                                                  

14、      # UserHost: rootroot  localhost                                    &#

15、160;                       # Query_time: 11 Lock_time: 0 Rows_sent: 1 Rows_examined: 6552961        select

16、0;count(*) from t_user;                                            

17、60;                                   从日志中,可以发现查询时间超过5 秒的SQL,而小于5秒的没有出现在此日志中。如果慢查询日志中记录内容很多,可以使用mysqldumpslow工具(MySQL客户端安装自带)

18、来对慢查询日志进行分类汇总。mysqldumpslow对日志文件进行了分类汇总,显示汇总后摘要结果。进入log的存放目录,运行rootmysql_data#mysqldumpslow  slow-query.log                                &

19、#160;Reading mysql slow query log from slow-query.log                            Count: 2 Time=11.00s (22s) Lock=0.00s&#

20、160;(0s) Rows=1.0 (2), rootrootmysql    select count(N) from t_user;                               &

21、#160;                mysqldumpslow命令/path/mysqldumpslow -s c -t 10 /database/mysql/slow-query.log                    

22、60; 这会输出记录次数最多的10条SQL语句,其中:-s, 是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙;-t, 是top n的意思,即为返回前面多少条的数据;-g, 后边可以写一个正则匹配模式,大小写不敏感的;例如:/path/mysqldumpslow -s r -t 10 /database/mysql/slow-log              &#

23、160;                  得到返回记录集最多的10个查询。/path/mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log       得到按照时间排序的前10条里面含有左连接的查询语句。使用mysqldumpslow命令可以非常明确的得到各种我们需要的查

24、询语句,对MySQL查询语句的监控、分析、优化是MySQL优化非常重要的一步。开启慢查询日志后,由于日志记录操作,在一定程度上会占用CPU资源影响mysql的性能,但是可以阶段性开启来定位性能瓶颈。explain分析查询使用 EXPLAIN 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。通过explain命令可以得到: 表的读取顺序 数据读取操作的操作类型 哪些索引可以使用 哪些索引被实际使用 表之间的引用 每张表有多少行被优化器查询EXPLAIN字段:ØTable:显示这一行

25、的数据是关于哪张表的Øpossible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句Økey:实际使用的索引。如果为NULL,则没有使用索引。MYSQL很少会选择优化不足的索引,此时可以在SELECT语句中使用USE INDEX(index)来强制使用一个索引或者用IGNORE INDEX(index)来强制忽略索引Økey_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好Øref:显示索引的哪一列被使用了,如果可能的话,是一个常数Ørows:MySQL认为必

26、须检索的用来返回请求数据的行数Øtype:这是最重要的字段之一,显示查询使用了何种类型。从最好到最差的连接类型为system、const、eq_reg、ref、range、index和ALLnsystem、const:可以将查询的变量转为常量.  如id=1; id为 主键或唯一键.neq_ref:访问索引,返回某单一行的数据.(通常在联接时出现,查询使用的索引为主键或惟一键)nref:访问索引,返回某个值的数据.(可以返回多行) 通常使用=时发生nrange:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西,并且该字段上建有索引时发生的

27、情况(注:不一定好于index)nindex:以索引的顺序进行全表扫描,优点是不用排序,缺点是还要全表扫描nALL:全表扫描,应该尽量避免ØExtra:关于MYSQL如何解析查询的额外信息,主要有以下几种nusing index:只用到索引,可以避免访问表. nusing where:使用到where来过虑数据. 不是所有的where clause都要显示using where. 如以=方式访问索引.nusing tmporary:用到临时表nusing filesort:用到额外的排序. (当使用order by v1,而没用到索引时,就会使用额外的排序)nrange c

28、hecked for eache record(index map:N):没有好的索引. profiling分析查询通过慢日志查询可以知道哪些SQL语句执行效率低下,通过explain我们可以得知SQL语句的具体执行情况,索引使用等,还可以结合show命令查看执行状态。如果觉得explain的信息不够详细,可以同通过profiling命令得到更准确的SQL执行消耗系统资源的信息。profiling默认是关闭的。可以通过以下语句查看  打开功能: mysql>set profiling=1; 执行需要测试的sql 语句:mysql> show profi

29、lesG; 可以得到被执行的SQL语句的时间和IDmysql>show profile for query 1; 得到对应SQL语句执行的详细信息Show Profile命令格式:SHOW PROFILE type , type                                 

30、        FOR QUERY n                                         

31、                       LIMIT row_count OFFSET offset                        

32、0;    type:                                             

33、;                                         ALL          

34、                                                  

35、                     | BLOCK IO                             

36、                                           | CONTEXT SWITCHES      

37、60;                                              | CPU     &

38、#160;                                                 &

39、#160;                        | IPC                           

40、;                                                   

41、60;   | MEMORY                                              

42、                                | PAGE FAULTS                  &#

43、160;                                              | SOURCE    

44、60;                                                  &#

45、160;                  | SWAPS                    以上的16rows是针对非常简单的select语句的资源信息,对于较复杂的SQL语句,会有更多的行和字段,比如converting HEAP

46、to MyISAM 、Copying to tmp table等等,由于以上的SQL语句不存在复杂的表操作,所以未显示这些字段。通过profiling资源耗费信息,我们可以采取针对性的优化措施。 测试完毕以后 ,关闭参数:mysql> set profiling=0  2     索引及查询优化 索引的类型Ø 普通索引:这是最基本的索引类型,没唯一性之类的限制。Ø 唯一性索引:和普通索引基本相同,但所有的索引列值保持唯一性。Ø 主键:主键是

47、一种唯一索引,但必须指定为”PRIMARY KEY”。Ø 全文索引:MYSQL从开始支持全文索引和全文检索。在MYSQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。大多数MySQL索引(PRIMARY KEY、UNIQUE、INDEX和FULLTEXT)使用B树中存储。空间列类型的索引使用R-树,MEMORY表支持hash索引。单列索引和多列索引(复合索引)索引可以是单列索引,也可以是多列索引。对相关的列使用索引是提高SELECT操作性能的最佳途径之一。多列索引:MySQL可以为多个列创建索引。一个索引可以包括15个列。

48、对于某些列类型,可以索引列的左前缀,列的顺序非常重要。多列索引可以视为包含通过连接索引列的值而创建的值的排序的数组。一般来说,即使是限制最严格的单列索引,它的限制能力也远远低于多列索引。最左前缀多列索引有一个特点,即最左前缀(Leftmost Prefixing)。假如有一个多列索引为key(firstname lastname age),当搜索条件是以下各种列的组合和顺序时,MySQL将使用该多列索引:firstname,lastname,agefirstname,lastnamefirstname也就是说,相当于还建立了key(firstname lastname)和key(firstna

49、me)。索引主要用于下面的操作:Ø 快速找出匹配一个WHERE子句的行。Ø 删除行。当执行联接时,从其它表检索行。Ø 对具体有索引的列key_col找出MAX()或MIN()值。由预处理器进行优化,检查是否对索引中在key_col之前发生所有关键字元素使用了WHERE key_part_# = constant。在这种情况下,MySQL为每个MIN()或MAX()表达式执行一次关键字查找,并用常数替换它。如果所有表达式替换为常量,查询立即返回。例如:SELECT MIN(key2), MAX (key2)

50、  FROM tb WHERE key1=10;Ø 如果对一个可用关键字的最左面的前缀进行了排序或分组(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有关键字元素后面有DESC,关键字以倒序被读取。Ø 在一些情况中,可以对一个查询进行优化以便不用查询数据行即可以检索值。如果查询只使用来自某个表的数字型并且构成某些关键字的最左面前缀的列,为了更快,可以从索引树检索出值。SELECT key_part3 FROM tb W

51、HERE key_part1=1有时MySQL不使用索引,即使有可用的索引。一种情形是当优化器估计到使用索引将需要MySQL访问表中的大部分行时。(在这种情况下,表扫描可能会更快些)。然而,如果此类查询使用LIMIT只搜索部分行,MySQL则使用索引,因为它可以更快地找到几行并在结果中返回。例如: 合理的建立索引的建议:(1)  越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。 (2)  简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日

52、期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。(3)  尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值 这部分是关于索引和写SQL语句时应当注意的一些琐碎建议和注意点。1. 当结果集只有一行数据时使用LIMIT 12. 避免SELECT *,始终指定你需要的列从表中读取越多的数据,查询会变得更慢。他增加了磁盘需要操作的时间,还是在数据库服务器与WEB服务器是独立分开的情况下。你将

53、会经历非常漫长的网络延迟,仅仅是因为数据不必要的在服务器之间传输。3. 使用连接(JOIN)来代替子查询(Sub-Queries)       连接(JOIN). 之所以更有效率一些,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。4. 使用ENUM、CHAR 而不是VARCHAR,使用合理的字段属性长度5. 尽可能的使用NOT NULL6. 固定长度的表会更快7. 拆分大的DELETE 或INSERT 语句8. 查询的列越小越快  Where条件在查询中,WHERE条件也是一个比

54、较重要的因素,尽量少并且是合理的where条件是很重要的,尽量在多个条件的时候,把会提取尽量少数据量的条件放在前面,减少后一个where条件的查询时间。有些where条件会导致索引无效:Ø where子句的查询条件里有!=,MySQL将无法使用索引。Ø where子句使用了Mysql函数的时候,索引将无效,比如:select * from tb where left(name, 4) = xxxØ 使用LIKE进行搜索匹配的时候,这样索引是有效的:select * from tbl1 where name like xxx%,而lik

55、e %xxx% 时索引无效 三、    配置优化安装MySQL后,配置文件f在 /MySQL安装目录/share/mysql目录中,该目录中还包含多个配置文件可供参考,有my-f ,my-f,  my-f,my-f,分别对应大中小型数据库应用的配置。win环境下即存在于MySQL安装目录中的.ini文件。 下面列出了对性能优化影响较大的主要变量,主要分为连接请求的变量和缓冲区变量。1.   连接请求的变量:1)     max_connectionsMySQL的最大

56、连接数,增加该值增加mysqld 要求的文件描述符的数量。如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。数值过小会经常出现ERROR 1040: Too many connections错误,可以过conn%通配符查看当前状态的连接数量,以定夺该值的大小。show variables like max_connections 最大连接数show  status like max_used_connections响

57、应的连接数如下:mysql> show variables like max_connections;+-+| Variable_name| Value |+-+| max_connections | 256|+-+mysql> show status like max%connections;+-+| Variable_name      | Value |+-+-+| max_used_connections | 256|+-+-+max_used_connections / max_connections * 100% (理想

58、值 85%) 如果max_used_connections跟max_connections相同 那么就是max_connections设置过低或者超过服务器负载上限了,低于10%则设置过大。2)     back_logMySQL能暂存的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用。如果MySQL的连接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。back_log值指出在M

59、ySQL暂时停止回答新请求之前的短时间内有多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的TCP/IP连接的侦听队列的大小。当观察你主机进程列表(mysql> show full processlist),发现大量264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时,就要加大back_log 的值了。默认数值是50,可调优为128,对于Linux系统设置范围为小于512的整数。 3)

60、0;    interactive_timeout一个交互连接在被服务器在关闭前等待行动的秒数。一个交互的客户被定义为对mysql_real_connect()使用CLIENT_INTERACTIVE 选项的客户。 默认数值是28800,可调优为7200。 2.   缓冲区变量全局缓冲:4)     key_buffer_sizekey_buffer_size指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。通过检查状态值Key_read_requests和Key_rea

61、ds,可以知道key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低,至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE key_read%获得)。key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表,但是内部的临时磁盘表是MyISAM表,也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。举例如下:mysql> show variables like key_buffer_size;+-+| Variable_name

62、| Value      |+| key_buffer_size | 536870912 |+ -+key_buffer_size为512MB,我们再看一下key_buffer_size的使用情况:mysql> show global status like key_read%;+-+| Variable_name  | Value    |+-+| Key_read_requests| 27813678764 | Key_reads|  6798830    

63、0; |+-+一共有27813678764个索引读取请求,有6798830个请求在内存中没有找到直接从硬盘读取索引,计算索引未命中缓存的概率:key_cache_miss_rate Key_reads / Key_read_requests * 100%,设置在1/1000左右较好默认配置数值是8388600(8M),主机有4GB内存,可以调优值为268435456(256MB)。5)     query_cache_size使用查询缓冲,MySQL将查询结果存放在缓冲区中,今后对于同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果

64、。通过检查状态值Qcache_*,可以知道query_cache_size设置是否合理(上述状态值可以使用SHOW STATUS LIKE Qcache%获得)。如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况,如果Qcache_hits的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;如果Qcache_hits的值不大,则表明你的查询重复率很低,这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。此外,在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲。 与查询缓冲有关的参数还有query_cac

65、he_type、query_cache_limit、query_cache_min_res_unit。 query_cache_type指定是否使用查询缓冲,可以设置为0、1、2,该变量是SESSION级的变量。query_cache_limit指定单个查询能够使用的缓冲区大小,缺省为1M。query_cache_min_res_unit是在4.1版本以后引入的,它指定分配缓冲区空间的最小单位,缺省为4K。检查状态值Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多,这就表明查询结果都比较小,此时需要减小query_cache_min_res_unit。举例

66、如下:mysql> show global status like qcache%;+-+| Variable_name                  | Value       |+-+| Qcache_free_blocks       | 22756   

67、0;  | Qcache_free_memory    | 76764704    | Qcache_hits      | 213028692 | Qcache_inserts     | 208894227   | Qcache_lowmem_prunes   | 4010916      | Qcache_not_cached| 133850

68、31    | Qcache_queries_in_cache | 43560| Qcache_total_blocks          | 111212     |+-+mysql> show variables like query_cache%;+| Variable_name       | Value     |+| query_

69、cache_limit    | 2097152     | query_cache_min_res_unit     | 4096  | query_cache_size    | 203423744 | query_cache_type   | ON          | query_cache_wlock_invalidate | OFF 

70、|+查询缓存碎片率= Qcache_free_blocks / Qcache_total_blocks * 100%如果查询缓存碎片率超过20%,可以用FLUSH QUERY CACHE整理缓存碎片,或者试试减小query_cache_min_res_unit,如果你的查询都是小数据量的话。查询缓存利用率= (query_cache_size Qcache_free_memory) / query_cache_size * 100%查询缓存利用率在25%以下的话说明query_cache_size设置的过大,可适当减小;查询缓存利用率在80以上而且Qcache_lowmem_prunes &g

71、t; 50的话说明query_cache_size可能有点小,要不就是碎片太多。查询缓存命中率= (Qcache_hits Qcache_inserts) / Qcache_hits * 100%示例服务器查询缓存碎片率20.46,查询缓存利用率62.26,查询缓存命中率1.94,命中率很差,可能写操作比较频繁吧,而且可能有些碎片。每个连接的缓冲6)    record_buffer_size每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描,你可能想要增加该值。默认数值是131072(128K),可改为167731

72、20 (16M)7)     read_rnd_buffer_size随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySQL会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySQL会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。一般可设置为16M 8)     sort_buffer_size每个需要进行排序的线程分配该大小的一个缓冲区。增加这值加速ORDER BY或GROU

73、P BY操作。默认数值是2097144(2M),可改为16777208 (16M)。9)     join_buffer_size联合查询操作所能使用的缓冲区大小record_buffer_size,read_rnd_buffer_size,sort_buffer_size,join_buffer_size为每个线程独占,也就是说,如果有100个线程连接,则占用为16M*10010)  table_cache表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。通过检查峰值时间的状态值Open_tables和Opened_tables,可以决定是否需要增加table_cache的值。如果你发现open_tables等于table

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论