美文网首页MySQL
63-MySQL普通索引与唯一索引比较

63-MySQL普通索引与唯一索引比较

作者: 紫荆秋雪_文 | 来源:发表于2022-11-09 09:52 被阅读0次

    一、准备数据

    • 创建表
    CREATE TABLE test
    (
        id   INT PRIMARY KEY,
        k    INT NOT NULL,
        name VARCHAR(16),
        INDEX (k)
    );
    
    • 插入数据
    INSERT INTO test(id, k)
    VALUES (100,1),
           (200,2),
           (300,3),
           (400,4),
           (500,5),
           (600,6);
    

    二、查询过程

    • SQL
    SELECT id
    FROM test
    WHERE k = 5;
    
    • 对于普通索引来说,查找到满足条件的第一个记录(5,500)后,需要查找下一个记录,直到碰到第一个不满足k=5条件的记录
    • 对于唯一索引来说,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索
    • 那么,这个不同带来的性能差距会有多少呢?答案是, 微乎其微

    三、更新过程

    为了说明普通索引唯一索引更新语句性能的影响这个问题,介绍一下change buffer

    3.1、普通索引更新过程

    • 1、当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下, InooDB会将这些更新操作缓存在change buffer中 ,这样就不需要从磁盘中读入这个数据页了。

    • 2、在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行change buffer中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。

    • 3、将change buffer中的操作应用到原数据页,得到最新结果的过程称为 merge 。除了 访问这个数据页 会触发merge外,系统有 后台线程会定期 merge。在 数据库正常关闭(shutdown) 的过程中,也会执行merge操作

    • 4、如果能够将更新操作先记录在change buffer减少读磁盘 ,语句的执行速度会得到明显的提升。而且,数据读入内存是需要占用 buffer pool 的,所以这种方式还能够 避免占用内存 ,提高内存利用率

    3.2、唯一索引更新过程

    唯一索引的更新就不能使用change buffer

    四、change buffer 的使用场景

    • 1、普通索引唯一索引应该怎么选择?其实,这两类索引在查询能力上是没差别的,主要考虑的是对 更新性能 的影响。所以,建议你 尽量选择普通索引

    • 2、在实际使用中会发现, 普通索引change buffer 的配合使用,对于 数据量大 的表的更新优化还是很明显的

    • 3、如果所有的更新后面,都马上 伴随着对这个记录的查询 ,那么你应该 关闭change buffer 。而在其他情况下,change buffer都能提升更新性能

    • 4、由于唯一索引用不上change buffer的优化机制,因此如果 业务可以接受 ,从性能角度出发建议优先考虑非唯一索引。但是如果"业务可能无法确保"的情况下,怎么处理呢?

      • 首先业务正确性优先 。我们的前提是“业务代码已经保证不会写入重复数据”的情况下,讨论性能问题。如果业务不能保证,或者业务就是要求数据库来做约束,那么没得选,必须创建唯一索引。这种情况下,本节的意义在于,如果碰上了大量插入数据慢、内存命中率低的时候,给你多提供一个排查思路
      • 然后,在一些“ 归档库 ”的场景,你是可以考虑使用唯一索引的。比如,线上数据只需要保留半年,然后历史数据保存在归档库。这时候,归档数据已经是确保没有唯一键冲突了。要提高归档效率,可以考虑把表里面的唯一索引改成普通索引

    相关文章

      网友评论

        本文标题:63-MySQL普通索引与唯一索引比较

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