MySQL的索引策略(2)

上文提到了用自增主键作聚簇索引列,能够方便插入操做。但高并发场景下,主键的上界集中了全部的插入,可能致使间隙锁竞争(间隙锁是innodb中行锁的一种, 可是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要做用是为了防止出现幻读;对符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫作“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁))。同时,自增字段的锁机制也可能成为热点。mysql

  • 覆盖索引

指包含了全部须要查询字段的索引。覆盖索引的优点以下sql

  1. 下降数据访问量。索引列数据一般远少于整行数据。
  2. 优化范围查询。由于索引是按顺序创建的。
  3. 内存中保存索引,因此可避免访问磁盘/产生系统调用。
  4. 聚簇索引中,二级主键的覆盖查询能够直接在叶子节点读取数据,从而避免了再次访问聚簇索引取值的过程。这个是覆盖索引最多见的用途

覆盖索引的核心是:索引结构保存相关列的值。因此,通常用在B+树索引。并发

  • 索引扫描排序

​​​​​​​前篇提到,索引的三个用途是:SELECT、ORDER BY、GROUP BY。高并发

若是索引不能覆盖全部列,则读取数据的过程是:...->索引中读取n行相关信息->查找n行->索引读取n+1行数据->...。这样比顺序扫描全表还慢。因此使用索引扫描排序须知足条件:性能

  1. 索引列的顺序与ORDER BY的顺序彻底一致。col1, col2..
  2. 索引排序方向与ORDER BY的排序方向一致。ASC, DESC。
  3. 最左前缀。
  4. 多表关联时,ORDER BY的字段必须都在第一张表。
  • 合理冗余索引
CREATE TABLE test (
ID INT NOT NULL PRIMARY KEY,
A INT NOT NULL,
B text NOT NULL,
UNIQUE(ID),
INDEX(ID)
) ENGINE=InnoDB;

上述表的主键限制、惟一限制都是经过索引实现的。因此,这张表的ID列上,存在三个索引。这种冗余是没有意义的。优化

或者说,把(A)索引扩展为(A, ID),这样也是没有意义的。聚簇索引的二级索引的叶节点,自己就包含主键信息。spa

SELECT A,B from test where A=2;

对上述查询,若是咱们扩展索引(A)为(A, B),就能够利用覆盖索引,加速查询。但B字段很长,会致使只取A字段时性能降低。此时,能够同时保留(A)和(A, B)索引,虽然对A列来讲是冗余索引,但总体查询的性能提高了 。code

  • 索引和锁

​​​​​​​减小锁的行数,有两个直接好处:1.减小加锁开销 2.减小事务间的竞争。排序

InnoDB在访问行时才会加锁;因此若是索引能帮助筛选掉不须要访问的行,就能减小加锁量。索引

不然,InnoDB须要作全表扫描,锁住全部的行。

InnoDB在二级索引上使用共享锁,在访问主键索引时用排他锁。因此,在二级索引访问时,其余事务依然能够写入数据,那么就没法使用覆盖索引。

  • 其余细节
  1. ​​​​​​​把最常出现的where的列放在最左。在不须要该筛选条件时,能够IN (全部值)以知足最左前缀。在创建合理索引的同时,也考虑针对索引优化查询。
  2. 范围查询尽可能放在最右。由于范围索引以后的索引都会失效。多个范围查询时,特别须要避免范围查询;替代方案是用穷举 IN方案,此时要注意,多个IN之间,在优化时作笛卡尔积,产生m*n*...个=条件的查询;不能穷举的状况(datatime >= ,最近访问),能够设置标志列,实时更新,在业务上避免使用范围查询。
  3. 优化排序。
    mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;

    这个查询中,可建立(sex, rating)索引帮助排序,不要局限于where后的条件。

  4. 翻页查询

    mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10;
    
    mysql> SELECT <cols> FROM profiles INNER JOIN (
    -> SELECT <primary key cols> FROM profiles
    -> WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
    -> ) AS x USING(<primary key cols>);

    偏移量越大,会须要更多的扫描来丢弃不须要的数据;能够在业务上限制翻页数量。下面一条是一种优化查询,先用覆盖索引(3中创建的索引)快速查询到主键,而后取值。

相关文章
相关标签/搜索