InnoDB中索引的实现

B+树索引的使用

5.6.1 不同应用中B+树索引的使用

在OLTP应用中,查询操作只从数据库中取得一小部分数据,一般可能都在10条记录以下,甚至在很多时候只取1条记录,如根据主键值来取得用户信息,根据订单号取得订单的详细信息,这都是典型OLTP应用的查询语句。在这种情况下,B+树索引建立后,对该索引的使用应该只是通过该索引取得表中少部分的数据。这时建立B+树索引才是有意义的。

OLAP应用需要分析特定的场景来进行创建。

5.6.2 联合索引

从本质上来说,联合索引也是一棵B+树,不同的是联合索引的键值的数量不是1,而是大于等于2。

InnoDB中索引的实现_第1张图片

我们可以看到,多个键值的B+树是按照(a,b)组合排序,这样的方式对于:

select * from table where a=xxx and b=xxx 和select * from table where a=xxx是可以走索引的,但是对于select * from table where b=xxx是不能走索引的。

5.6.3 覆盖索引

InnoDB存储引擎支持覆盖索引(covering index,或称索引覆盖),即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。使用覆盖索引的一个好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。

5.6.4 优化器选择不使用索引的情况

当执行EXPLAIN命令进行SQL语句的分析时,会发现优化器并没有选择索引去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据。这种情况多发生于范围查找、JOIN 链接操作等情况下。

现象:

使用select * from order where orderid > 10000;这条语句不会走 orderid 辅助索引,而是会走聚集索引,因为查询的是*,代表所有字段。如果要求访问的数据量很小,则优化器还是会选择辅助索引,但是当访问的数据占整个表中数据的蛮大一部分时(一般是20%左右),优化器会选择通过聚集索引来查找数据。

如果需要强制走某个索引,那么需要用到 force index :

select * from order FORCE INDEX(OrderID) where orderid > 10000;

5.6.5 索引提示

MySQL数据库支持索引提示(INDEX HINT),显式地告诉优化器使用哪个索引。

个人总结以下两种情况可能需要用到INDEX HINT:

  1. MySQL数据库的优化器错误地选择了某个索引,导致SQL语句运行的很慢。这种情况在最新的MySQL数据库版本中非常非常的少见。优化器在绝大部分情况下工作得都非常有效和正确。这时有经验的DBA或开发人员可以强制优化器使用某个索引,以此来提高SQL运行的速度。
  2. 某SQL语句可以选择的索引非常多,这时优化器选择执行计划时间的开销可能会大于SQL语句本身。例如,优化器分析Range查询本身就是比较耗时的操作。这时DBA或开发人员分析最优的索引选择,通过IndexHint来强制使优化器不进行各个执行路径的成本分析,直接选择指定的索引来完成查询。

MySQL中HINT的用法:

select * from t USE INDEX(a) WHERE a=1 AND b=2;

USE INDEX只是告诉优化器可以选择该索引,实际上优化器还是会再根据自己的判断进行选择。

 

你可能感兴趣的:(数据库专栏:InnoDB原理,数据库,mysql,sql)