数据库架构--SQL查询优化

查询优化,索引优化,库表结构优化需要齐头并进

一、如何获取有性能问题的SQL

1、通过用户反馈获取存在性能问题的SQL

2、通过慢查日志获取存在性能问题的SQL

2.1、磁盘IO和存储日志所需要的磁盘空间

2.2、存储日志所需要的大量的磁盘空间

 

slow_query_log 启动停止记录慢查日志

set gloal slow_query_log=on

slow_query_log_file 指定慢查日志的存储路径及文件

long_query_time 指定记录慢查日志SQL执行时间的伐值

扫描二维码关注公众号,回复: 3037407 查看本文章

long_queries_not_using_indexes 是否记录未使用索引的SQL

常用的慢查询日志分析工具:mysqldumpslow

汇总除了查询条件外其它完全相同的SQL,并将分析结果按照参数中所指定的顺序输出。


mysqldumpslow -s r -t 10 slow-mysql.log

-s order(c,t,l,r,at,al,ar) 指定按哪种排序方式输出结果

c: 总次数

t: 总时间

l: 锁的时间

r: 总数据行

at,al,ar:t,l,r平均数

-t top 指定取前几条作为结束输出


使用慢查询日志分析工具(pt-query-digest)


3、实时获取存在性能问题的SQL   

information_schema.processlist


二、为什么查询会慢

1、客户端发送SQL请求给服务器

2、服务器检查是否可以在查询缓存中命中该SQL

3、服务器端进行SQL解析,预处理,再由路由器生成对应的执行计划

4、根据执行计划,调用存储引擎API来查询数据

5、将结果返回给客户端


对于一个读写频繁的系统使用查询缓存很可能会降低查询处理的效率


query_cache_type 设置查询缓存是否可用

demand 表示只有在查询语句中使用SQL_CACHE和SQL_NO_CACHE来控制是否需要缓存

query_cache_size 设置查询缓存的内存大小

query_cache_limit 设置查询缓存可用存储的最大值

query_cache_wlock_invaildate 设置数据表被锁后是否返回缓存中的数据

query_cache_min_res_unit 设置查询缓存分配的内存块最小单位


三、MySQL依照这个执行计划和存储引擎进行交互

这个阶段包含多个字过程

1、解析SQL,预处理,优化SQL执行计划

2、语法解析阶段是通过关键字对MySQL语句进行解析,并生成一颗对应的“解析树”

3、MySQL解析器将使用MySQL语法规则验证和解析查询

4、包括检查语法是否使用了准确的关键字

5、关键字是否正确等

6、预处理阶段是根据MySQL规则进一步检查解析树是否合法

7、检查查询中所涉及的表和数据列是否存在及名字或别名是否存在歧义等等

8、语法检查全部通过后,查询优化器就可以生成查询计划


四、会造成MySQL生成错误的执行计划的原因

1、统计信息不准确

2、执行计划中的成本估算不等同于实际的执行计划成本

3、MySQL优化器所认为最优可能与你所认为最优的不一样

4、MySQL从不考虑其它并发的查询,这可能会影响当前查询的速度

5、MySQL有时候也是会基于一些固定的规则来生成执行计划  

6、MySQL不会考虑不受其控制的成本


五、MySQL优化器可优化的SQL类型

1、重新定义表的关联顺序

2、将外连接转成内连接

3、使用等价交换规则

4、优化count(),min(),max()

5、将一个表达数转化为常数表达式

6、子查询优化

7、提前终止查询

8、对in()条件进行优化


六、如何确定查询处理各个阶段所消耗的时间

1、使用profile(已经过时了)

1.1、set profiling=1

 启动profile,这是一个session级的配制

1.2、执行查询

1.3、show profiles;查看每一个查询所消耗的总时间的信息

1.4、show profile for query N;查询的每个阶段所消耗的时间


2、使用performance_schema(mysql5.5之后)

use performance_schema

update setup_instruments set enabled=‘YES’,time=‘YES’ where name like ‘stage%’;

update setup_consumers set enabled=‘yes’ where name like ‘events%;


七、特殊SQL的查询优化

1、大表的更新和删除

分段进行

2、对大表结构的修改

2.1、对表中的列的字段类型进行修改,改变字段的宽度是还是会锁表,无法解决主从数据库延迟的问题 

2.2、解决方法:建一个新表,同步数据,老表建立触发器,同步到新表,再使用排他锁,最后重命名新表  

2.3、使用工具:pt-online-schema-change


3、优化not in 和< >查询:使用join on 查询

4、使用汇总表优化查询


猜你喜欢

转载自blog.csdn.net/xiaochen1999/article/details/80906073