zoukankan      html  css  js  c++  java
  • mysql数据库优化思路

    1.设置合适的主键和索引

      (1).设置主键和索引的字段尽量不要选取经常修改的字段,同时索引的个数一般不宜超过6个;

      (2).sql语句中like  “%str%” 不支持索引, "str%"号是支持索引的;

      (3).不要在查询语句前面使用函数,否则会导致索引不生效,如,where str=substring(“hello world”,6,8),这样是可以走索引的,但是 where substring(str,6,8)=“hello world” 是不会命中索引的;

      (4).建立索引的字段要区分度比较高,比如user表中有一个性别字段,性别字段无非男女两种值,区分度不好,建立索引效果不好,要选择区分度高的字段

    2.优化sql语句

      (1).尽量避免使用 select * from t ,用具体的字段列表代替“*”,返回有用的字段;

      (2).应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

    select id from t where num is null

        (3).应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描;

        (4).尽量避免使用“or”连接条件,可以使用union来优化,如:select id from t where num=10 or Name = 'admin', 可以这样查询:

    select id from t where num = 10
    union all
    select id from t where Name = 'admin'
     (5).尽量避免使用in 和 not in 也要慎用,否则会导致全表扫描,如:
    select id from t where num in(1,2,3)

      对于连续的数值,能用 between 就不要用 in 了:

    select id from t where num between 1 and 3

      很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)

      用下面的语句替换:

    select num from a where exists(select 1 from b where num=a.num)
    

      (6).应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where num/2 = 100

      应改为:

    select id from t where num = 100*2
    

      (7).应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

    select id from t where substring(name,1,3) = ’abc’ -–name以abc开头的id
    select id from t where datediff(day,createdate,’2005-11-30′) = 0 -–‘2005-11-30’ --生成的id

      应改为:

    select id from t where name like 'abc%'
    select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
    

      (8).对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

      (9).select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。

    3.数据库性能优化

     (1).选择正确的数据库引擎

                mysql比较常用的数据库引擎有两种,一种是innodb、一种是myisam  

    MyISAM

    • 不需要事务支持(不支持)
    • 并发相对较低(锁定机制问题)
    • 数据修改相对较少(阻塞问题),以读为主
    • 数据一致性要求不是非常高
    1. 尽量索引(缓存机制)
    2. 调整读写优先级,根据实际需求确保重要操作更优先
    3. 启用延迟插入改善大批量写入性能
    4. 尽量顺序操作让insert数据都写入到尾部,减少阻塞
    5. 分解大的操作,降低单个操作的阻塞时间
    6. 降低并发数,某些高并发场景通过应用来进行排队机制
    7. 对于相对静态的数据,充分利用Query Cache可以极大的提高访问效率
    8. MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问

    InnoDB 

    • 需要事务支持(具有较好的事务特性)
    • 行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成
    • 数据更新较为频繁的场景
    • 数据一致性要求较高
    • 硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO
    1. 主键尽可能小,避免给Secondary index带来过大的空间负担
    2. 避免全表扫描,因为会使用表锁
    3. 尽可能缓存所有的索引和数据,提高响应速度
    4. 在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交
    5. 合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性
    6. 避免主键更新,因为这会带来大量的数据移动

     (2).优化数据库访问

        这个优化法则归纳为5个层次:

        1、  减少数据访问(减少磁盘访问)

        2、  返回更少数据(减少网络传输或磁盘访问)

        3、  减少交互次数(减少网络传输)

        4、  减少服务器CPU开销(减少CPU及内存开销)

        5、  利用更多资源(增加资源)

        以下是每个优化法则层级对应优化效果及成本经验参考:

    优化法则

    性能提升效果

    优化成本

           减少数据访问

    1~1000

    返回更少数据

    1~100

    减少交互次数

    1~20

    减少服务器CPU开销

    1~5

    利用更多资源

    @~10

       (3).读写分离

               在数据库并发大的情况下,最好的做法就是进行横向扩展,增加机器,以提升抗并发能力,而且还兼有数据备份功能

     
     
    当你发现自己的才华撑不起野心时,就请安静下来学习吧
  • 相关阅读:
    Redis做为缓存的几个问题
    Python——操作smb文件服务器(上传和下载)
    Python——assert、isinstance的用法
    centos7-修改默认python为3
    mqtt
    如何编译生成 mkfs.ubifs、ubinize 工具
    2020-2笔记
    2020-1笔记
    C语言中getopt()和getopt_long()函数的用法
    buildroot
  • 原文地址:https://www.cnblogs.com/smallVampire/p/12016544.html
Copyright © 2011-2022 走看看