美文网首页数据库
mysql索引优化

mysql索引优化

作者: 味道_3a01 | 来源:发表于2018-09-28 16:44 被阅读2次

    存储引擎

    事务、读锁(共享锁)、写锁(排它锁)
    行锁、表锁
    行锁 只对指定的记录加锁,其他进程可对同一表中的其他记录进行操作
    表锁 对整张表进行加锁,写的话 阻塞,读 不影响

    表锁 速度快冲突多,行锁速度慢 冲突少

    存储引擎:官方存储引擎和第三方存储引擎
    InnoDB 支持事务、支持行锁、支持非锁定读、支持外键,支持最大64TB的数据量(第三方存储引擎)
    MyISAM 不支持事务,不支持行锁,支持表锁,支持全文检索,支持最大256TB的数据量。最大的缺陷是崩溃后无法安全恢复
    Memory 数据放在内存中,速度快,但因其支持表锁,所以并发性能差。重启或崩溃后数据全部丢失,只适合存临时表
    Archive 只支持INSERT和SELECT操作,支持行锁,但本身并不是事务安全的存储引擎,优点:压缩比1:10,适合存储历史数据、日志信息数据等

    索引

    目的:提高查询效率

    原理:通过不断地缩小想要获得数据的范围来筛选出最终想要的数据

    索引结构:b+树

    b+树索引结构

    磁盘块两个数据项,三个指针(分别指向两个数据项分割的三个区间)
    真实的数据在叶子节点

    b+树的查找过程

    二分查找
    3层的b+树,可以表示上百万的数据

    b+树的性质

    1.索引字段要尽量小
    2.索引最左匹配特性:b+树的数据项是复合的数据结构

    mysql存储引擎的实现

    MyISAM存储引擎

    MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址
    MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
    MyISAM的索引方式称为 非聚集索引

    InnoDB索引

    InnoDB的数据文件本身就是索引文件
    第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址

    如何建立合适的索引

    建立索引的原理

    最左匹配原则
    索引匹配的最左原则具体是说,假如索引列分别为A,B,C,顺序也是A,B,C:

    那么查询的时候,如果查询【A】【A,B】 【A,B,C】,那么可以通过索引查询

    • 如果查询的时候,采用【A,C】,那么C这个虽然是索引,但是由于中间缺失了B,因此C这个索引是用不到的,只能用到A索引
    • 如果查询的时候,采用【B】 【B,C】 【C】,由于没有用到第一列索引,不是最左前缀,那么后面的索引也是用不到了
    • 如果查询的时候,采用范围查询,并且是最左前缀,也就是第一列索引,那么可以用到索引,但是范围后面的列无法用到索引

    建立索引的常用技巧

    1. 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

    2. =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

    3. 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录

    4. 索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);

    5. 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可,当然要考虑原有数据和线上使用情况

    MySQL优化

    配置优化

    基本配置

    • innodb_buffer_pool_size:缓冲池是数据和索引缓存的地方,典型的值是5-6GB(8GB内存),20-25GB(32GB内存),100-120GB(128GB内存)
    • innodb_log_file_size:redo日志的大小,redo日志的总尺寸被限定在4GB(默认可以有2个log文件)
    • max_connections:默认151个,可以设置更大,如300;不能设置的过大,如1000,当服务器运行1000个或更高的活动事务时会变的没有响应。在应用程序中使用数据库连接池

    InnoDB配置

    • innodb_file_per_table:InnoDB是否需要将所有表的数据和索引存放在共享表空间里
    • innodb_flush_log_at_trx_commit:默认值为1,表示InnoDB完全支持ACID特性
    • innodb_flush_method:数据和日志写入硬盘的方式,O_DIRECT、fdatasync(默认值)
    • innodb_log_buffer_size:尚未执行的事务分配的缓存;看看Innodb_log_waits状态变量,如果它不是0,增加innodb_log_buffer_size。

    其他配置

    • query_cache_size:设置query_cache_size = 0(现在MySQL 5.6的默认值)并利用其他方法加速查询
    • log_bin:开启二进制日志
    • skip_name_resolve:建议在启动服务器时关闭skip_name_resolve选项而不进行DNS查找。唯一的局限是之后GRANT语句中只能使用IP地址了,因此在添加这项设置到一个已有系统中必须格外小心。

    SQL调优

    有慢查询的SQL,系统或者server可以开启慢查询日志,尤其是线上系统,一般都会开启慢查询日志,如果有慢查询,可以通过日志来过滤

    慢查询优化基本步骤

    1. 先运行看看是否真的很慢,注意设置SQL_NO_CACHE
    2. where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
    3. explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
    4. order by limit 形式的sql语句让排序的表优先查
    5. 了解业务方使用场景
      6 . 加索引时参照建索引的几大原则
    6. 观察结果,不符合预期继续从0分析

    常用调优手段

    执行计划explain

    MySQL优化系列(二)--查找优化(1)(非索引设计)

    通过profiling命令得到更准确的SQL执行消耗系统资源的信息

    优化思路:避免全表扫描 & 注重SQL语句写法 & 索引

    mysql支持的最大连接数:默认是100,最大是16384

    关注公众号,获取海量免费java进阶视频

    相关文章

      网友评论

        本文标题:mysql索引优化

        本文链接:https://www.haomeiwen.com/subject/nrmpoftx.html