对于一个小的应用,也许就不需要什么优化,而对于一些数据量稍微大一些的项目 ,数据优化就是必须的。
笔者曾经一个项目 有几张表 每日新增几百万行,最多的一张表 每天新增记录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基础课程的可以私信或者评论,我把我自己学习过的或者收集到的教程分享。