mysql 优化专题

对于一个小的应用,也许就不需要什么优化,而对于一些数据量稍微大一些的项目 ,数据优化就是必须的。

笔者曾经一个项目 有几张表 每日新增几百万行,最多的一张表 每天新增记录3千万行以上。对于这样的表不得不做一些处理,来提升数处理速度和效率。

常见的提升数据库效率的手段有

1   主键+索引,必要时使用联合索引。注意联合索引的左生效原则。

2   引擎设置  使用最多 InnoDB  MyISAM 注意其中的区别,InnoDB 行级锁 ,事务,InnoDB是聚簇索引(叶子节点存数据),MyISAM是非聚簇索引(叶子节点存指针)

3   避免使用临时表 ,临时表也是有读写操作的,开销比较大

4   使用事务 确保数据安全,

5   恰当的字段设置 ,表空间优化

6   join 代替子查询  注意join的特点 inner join  left join right join

      inner 是获取2表的交集部分 left 获取左表全部,right 获取右表的全部  

7   优化查询语句,

 最好是在相同类型的字段间进行比较的操作,在建有索引的字段上尽量不要使用函数进行操作。在搜索字符型字段时,我们有时会使用LIKE关键字和通配符,这种做法虽然简单,但却也是以牺牲系统性能为代价的。应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。

数据配置上的优化

tmp_table_size

max_connections

table cache

slow_launch_time=2 查询大于某个时间的值(单位:s)

slow_query_log=on/off 开启关闭慢查询日志

slow_query_log_file=/opt/data/xxx.log 慢查询日志位置

key_buffer_size  索引缓存大小,是对MyISAM表性能影响最大的一个参数 ,32bit平台上,此值不要超过2GB,64bit平台不用做此限制,但也不要超过4GB

sort_buffer_size

show global status like 'table%';

表扫描率 = Handler_read_rnd_next / Com_select 

如果:表扫描率超过4000,说明进行了太多表扫描,很有可能索引没有建好,增加read_buffer_size值会有一些好处,但最好不要超过8MB。

open_files_limit

推荐 Open_files / open_files_limit * 100% <= 75%

代码上的优化  

开启查询缓存

统一SQL语句的写法,空格、大小写保持整站一致。尽量避免使用select *,返回无用的字段会降低查询效率。

不要把SQL语句写得太复杂,如果语句长可以将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。

    使用临时表暂存结果,简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。

尽量避免使用in 和not in,会导致数据库引擎放弃索引进行全表扫描。

尽量避免使用or,会导致数据库引擎放弃索引进行全表扫描。

尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描。

尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描。

减少跨库查询和大表连接操作(分割你的表,减小表尺寸)。存储过程、视图、函数的适当使用。


最后 回到本例最上面的案例,我们项目中实行了按天分表,多条件对应的联合索引,主键等,最多一天9千多万的数据的,统计查询耗时约7秒。数据量3千万行的表 大约不到3秒。


需要PHP基础课程的可以私信或者评论,我把我自己学习过的或者收集到的教程分享。

你可能感兴趣的:(mysql 优化专题)