首页 » Web前端 » phpmysql慢查询技巧_教你若何优化MySQL慢查询SQL语句快速提升系统机能

phpmysql慢查询技巧_教你若何优化MySQL慢查询SQL语句快速提升系统机能

访客 2024-11-08 0

扫一扫用手机浏览

文章目录 [+]

运用系统性能测试过程中,性能优化是绕不开的话题,对测试职员而言,性能优化的第一站便是SQL语句的优化与剖析。
因此本文紧张以MySQL数据库为例,先容常见的慢查询SQL语句实行效率剖析与优化方法和大略示例,为致力于运用系统性能优化的从业职员供应一定参考和借鉴。

1慢查询定位

phpmysql慢查询技巧_教你若何优化MySQL慢查询SQL语句快速提升系统机能

(1)慢查询

phpmysql慢查询技巧_教你若何优化MySQL慢查询SQL语句快速提升系统机能
(图片来自网络侵删)

慢查询SQL语句,即在数据库实行耗时超过一定阈值的SQL语句,常见阈值为500~2000ms,可根据业务需求适当调度。
如存在大量慢查询语句会直接导致系统相应韶光变长,降落用户体验感,因此慢查询的定位与优化是SQL语句优化的紧张内容。

慢查询调优的第一步是准确定位慢查询语句,须要数据库开启慢查询日志记录功能,然后借助工具对日志进行剖析实现慢查询SQL语句的准确定位。

--慢查询开启状态、日志位置

show variables like`slow_query%`;

--慢查询命中时长

show variables like`long_query_time`;

(2)mysqldumpslow慢查询日志剖析

MySql数据库的慢查询SQL语句,可以借助mysqldumpslow工具进行剖析;其他类型数据库,可根据官方供应的技能文档采取对应的工具开展慢查询日志剖析。

慢查询日志剖析的常用参数解释如下:

例:用时最多的10条慢SQL(后半部分为slow_query_log_file地址)

sql mysqldumpslow-s t-t 10-g'select'/data/mysql/data/dcbi-3306/log/slow.log

2 SQL语句实行剖析

(1)SQL实行顺序

剖析SQL语句实行效率的第一步,须要理解一条SQL语句的实行顺序,从而为语句优化供应依据。
一样平常而言,实行顺序为:

from->where->group by->聚合函数(sum、avg)->having->打算公式->select字段->order by->limit

(2)explain关键字

SQL语句实行剖析可通过在SQL语句前添加“explain”关键字后,在数据库编辑器中实行查看语句详细的实行情形。

explain selectfrom table_name where columns_1=value_1 and columns_2=vales_2

(3)SQL实行操持返回结果解释

返回结果各列解释可按需查询干系资料,重点关注【type】、【ref】、【extra】反响查询效率的3列,以【type】为主即可。

(4)SQL实行效率剖析

explain语句根据【type】列的值判断SQL实行效率,效率从低到高依次为:

all<index<range<index_merge<ref<eq_ref<const<system。
一样平常而言,【type】列值至少要在(range,system)之间,实行效率才能达到较高水平。

(5)SQL语句实行效率比拟

在开展SQL优化的过程中,比拟两条SQL语句实行韶光验证优化效果时,须要明确语句实行过程中数据的存取办法。
根据数据库数据查询机制,若数据库内存中已存在目标数据,则直接从内存中获取数据,不再是从数据库物理磁盘获取数据。
这种情形下,当优化前SQL语句实行后,目标数据已暂存于数据库内存中时;实行优化后SQL语句时,则直接从数据库内存中获取数据,导致该语句实行韶光失落真。

为避免验证优化效果时,涌现上述SQL语句实行韶光失落真的情形,需在select关键字后添加SQL_NO_CACHE关键字声明,通过数据库引擎重新查询数据。
SQL_NO_CACHE指的是查询结果在内存展示后,直接从内存中开释,并非不从内存中读取数据。
因此,若在实行SQL_NO_CACHE之前已经查询过目标数据,导致目标数据已经在数据库内存中,则该语句失落效。

用法示例如下:

select SQL_NO_CACHE columns from table_name where column_1=vales_1 and columns_2=values_2;

须要解释的是,SQL_CACHE、SQL_NO_CACHE命令在MySQL 5.7.20开始废弃,MySQL 8.0后彻底移除,普通select命令即直接从数据库中获取数据,无需从数据库内存中获取数据。
其他类型数据库干系机制,按需查阅对应官方技能文档。

3.常见SQL优化方法

(1)索引覆盖

SQL优化最常见的方法,便是实现索引覆盖,即select后的查询列、where后的查询条件均包含索引,通过查询条件即可得到查询列数据。

常见索引覆盖场景:

1)利用主键索引,select后的查询列不包含主键,则无法实现索引覆盖;

2)利用非主键索引,select后的查询列包含非主键索引,可实现索引覆盖;

3)利用非主键索引,select后的查询列包含主键索引,可实现索引覆盖。

(2)最左匹配原则

MySQL建立联合索引(多列索引)时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。
详细是由于,索引最左列全局有序、别的列局部有序但全局无序,因此根据索引查询必须知足最左匹配原则,否则索引失落效。

基于最左匹配原则,在创建索引时,根据业务需求,where中利用最频繁的列放在最左边;

最左匹配原则,碰着范围查询(>、<、between)时会停滞匹配,即范围查询后的索引失落效;

示例1:某张表索引按序为(a,b,c),如筛选条件为where a=1 and b=2,索引a、b均被利用到;如筛选条件为where b=2,则因未利用a=1,不知足最左匹配,索引失落效;where a=1 and b>1 and c=3,因b为范围查询,b、c均索引失落效。

示例2:某张表索引按序为(a,b,c),个中b字段在表table的所有值均为常量02003,同一个查询有4种不同的SQL语句写法:

--SQL语句1

selectfrom table where c='62412001090472816354'

--SQL语句2

selectfrom table where b='02003'and c='62412001090472816354'

--SQL语句3

selectfrom table where a='344589'and b='02003'and c='62412001090472816354'

--SQL语句4

selectfrom table where a='344589'and c='62412001090472816354'

上述SQL语句实行3次均匀耗时分别为:

结论:SQL语句1、SQL语句2因不知足最左匹配原则,导致索引失落效,查询耗时较长;SQL语句3、SQL语句4利用到索引,查询速率较快;但SQL语句4因缺失落索引字段b,相对SQL语句3耗时较长,可见索引字段b即便在整张表中均为常量,列入where后的筛选条件,依然能提高查询效率。

(3)索引条件下推

目的:检索数据时采取组合索引,且第一索引非等值索引时,只管即便利用其他索引条件精准选择目标数据,减少数据多次回表判断是否符合目标数据的次数,以办理慢查询导致的性能问题。

方法:做事层(Server层)把查询事情下推到数据库引擎(InnoDB)去处理。

上风:减少回表查询次数,提高查询效率,降落数据库IO资源花费。

判断:explain SQL输出【extra】列结果为using index condition。

下面详细比拟利用下推和未利用下推时的数据库底层逻辑,进一步解释索引条件下推的上风。

1)利用下推

第一索引非等值索引的SQL语句利用索引条件时,运用层将查询要求发送至引擎层,引擎层根据索引条件,剔除不知足其他索引的数据,将剩余知足其他索引条件的数据返回运用层,只管即便少回表地检索到对应记录。

利用条件下推时,引擎层可直接剔除不知足非第一索引中各列的数据。

2)未利用下推

SQL语句存在多个索引时,数据库Server层将查询要求发送至引擎层处理,引擎层按索引顺序,返回符合要求的数据到运用层。

数据库Server层完成筛选后,再按序发送下一索引检索条件,多次重复,直到知足所有查询条件。

如此多次循环,导致数据库IO资源花费较高。

(4)小表驱动大表

根据表的结果集大小选择驱动表,一样平常利用小表作为驱动表

例如,某系统存在表table_a、表table_b,数据量分别为100万、10万,则查询两表关联数据时,将表table_b作为子表:

selectfrom table_a where column_1=''and column_2 in(select column_2 from table_b where...)

若必须利用大表table_a作为子表,则利用exists关键字。

selectfrom table_a where exists(select column_2 from table_b where...)

(5)in代替or

若where后查询条件中某字段存在多个值,则用in代替or。

selectfrom ar_ar_41 where ID_SHARD='10800000'and(NUM_SEQ_AR='11090141150000002'or NUM_SEQ_AR='11090141450000005');

selectfrom ar_ar_41 where ID_SHARD='10800000'and NUM_SEQ_AR in('11090141150000002','11090141450000005');

(6)分组避免排序

MySQL默认对所有group by字段进行排序,非必要情形下,分组避免排序。

SELECT goods_id,count()FROM t GROUP BY goods_id ORDER BY NULL;

(7)批量INSERT插入

插入多条数据时,只管即便避免逐条数据插入,优先选择批量数据插入(插入数据量在50条及以上)。

--批量数据插入

INSERT INTO t(id,name)VALUES(1,’Bea’),(2,’Belle’),(3,’Bernice’);

--逐条数据插入

INSERT INTO t(id,name)VALUES(1,’Bea’);

INSERT INTO t(id,name)VALUES(2,’Belle’);

INSERT INTO t(id,name)VALUES(3,’Bernice’);

4范例的索引失落效案例

表city的联合索引为(ID,CountryCode),非索引列(Name,District,Population)

(1)where索引列表达式打算

索引失落效

selectfrom world.city where ID+1=4000;

索引未失落效

selectfrom world.city where ID=4001;

(2)where索引列利用函数

索引失落效

selectfrom world.city where substring(CountryCode,1,2)='nl';

索引未失落效

selectfrom world.city where CountryCode like'nl%';selectfrom world.city where CountryCode like'nl_';

(3)or条件包含非索引列

索引失落效

selectfrom world.city where ID=4001 or Name='Simi Valley';

索引未失落效

selectfrom world.city where ID=4001 or CountryCode='USA';

(4)like模糊查询,%在字首

索引失落效

selectfrom world.city where CountryCode like'%nld%';

索引未失落效

selectfrom world.city where CountryCode like'nld%';

(5)不知足最左匹配原则

索引失落效

selectfrom world.city where CountryCode='USA'and Population=111351;

索引未失落效

selectfrom world.city where ID=4001 and CountryCode='USA'and Population=111351;

备注:最左匹配导致的索引失落效情形较多,详见最左匹配部分。

(6)索引列未设置为NOT NULL

MySQL实行查询时会判断字段是否为NOT NULL,该过程每每须要全表扫描,因此最好为索引添加NOT NULL约束,并设置默认值,利于索引利用、加速查询效率

5关注:insert ignore into导致的性能问题或锁表

insert ignore into会对插入的每一行数据取共享锁(S锁,其他事务只可读)做唯一键的检测,同时会对主键自增ID加意向锁(insert intension);

在主键较为繁芜的情形下,检测主键是否唯一时会一贯占用主键的插入意向锁,其他进程也想给主键ID添加插入意向锁的时候,产生冲突导致去世锁;

此外,代码中存在的insert replace into也需重点关注。

总结

SQL语句优化剖析,是从事性能测试剖析从业职员开展性能优化中的第一站,也是性能优化的基本技能,对系统性能提升具有主要浸染和意义。
在节制性能优化基本技能的根本上,还需结合业务需求、代码逻辑访问路径,准确评估不同优化方法的适用性,综合比拟不同优化方法事情本钱,采取合理高效的优化方法开展性能优化事情。

文末了,我约请你进入我们的软件测试学习互换群,大家可以一起磋商互换软件测试,共同学习软件测试技能、口试等软件测试方方面面,理解测试行业的最新趋势,助你快速进阶Python自动化测试/测试开拓,稳住当前职位同时走向高薪之路。

末了:

1)关注+私信回答:“测试”,可以免费领取一份10G软件测试工程师口试宝典文档资料。
以及相对应的视频学习教程免费分享!
,个中包括了有根本知识、Linux必备、Mysql数据库、抓包工具、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高等持续集成、测试架构开拓测试框架、性能测试等。

2)关注+私信回答:"入群" 就可以约请你进入软件测试群学习互换~~

标签:

相关文章

hook钩子php技巧_php的钩子hook你有没有用过

钩子定义钩子是编程里一个常见观点,非常的主要。它使得系统变得非常随意马虎拓展,(而不用理解其内部的实现机理,这样可以减少很多事情量...

Web前端 2024-12-10 阅读0 评论0

php排序元素技巧_PHP 数组排序

PHP - 数组排序函数在本章中,我们将逐一先容下列 PHP 数组排序函数:sort( - 对数组进行升序排列rsort( -...

Web前端 2024-12-10 阅读0 评论0