赞
踩
问:什么样的字段适合建索引
答:唯一、不为空、经常被查询的字段
Hash索引:底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储上没有任何顺序关系,对于区间查询无法直接通过索引查询,需要全表扫描。哈希索引只适合用于等值查询的场景
B+树索引:底层是多路平衡查询树,节点天然有序(左小于父,父小于右),所以对于范围查询不需要全表扫描,对任意节点所耗费的时间都是完全相同的
InnoDB存储引擎绝大多数情况下使用B+树建立索引。B+树索引并不能找到给定键对应的具体值,只能找到数据行对应的页,数据库把整个页读入内存中,并在内存中查找具体的数据行。
索引又可以分为聚簇索引和非聚簇索引:
聚簇索引:对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。存储数据的顺序和索引顺序一致,且一个表只能有一个聚簇索引。主键索引一般都是聚餐索引。
非聚簇索引(辅助索引):表数据存储顺序与索引顺序无关,叶子节点包含索引字段值以及指向数据页数据行的逻辑指针。
问:主键就是聚簇索引吗
答:InnoDB作为MySQL存储引擎时,默认按照主键进行聚簇,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有,InnoDB就会定义影藏的主键然后进行聚簇。所以一般在在创建主键的时候就自动创建的主键的聚簇索引
非聚簇的叶子节点存储的不是数据而是对应的主键的索引,根据这个主键的索引去聚簇索引查找数据,叫做回表。
问:非聚簇索引一定会回表查询吗
答:不一定,如果要查询的字段都命中了主键索引,也就是刚好在该B+树的叶子结点里,则不需要回表查询
问:聚簇索引查询只会查一次,而非聚簇索引一定需要回表查询多次吗
答:通过覆盖索引也可以只查询一次
覆盖索引:指查询语句的执行只用从索引中就能够取得,不必从数据表中读取,也可以称之为实现了索引覆盖。
查询优化器会比较所有的查询方案,最终选择成本最低的方案来执行
优化过程:
问:什么时候设置了索引但无法使用
答:根本原因是查询优化器决定不适用索引
主要使用在联合索引中。
如果我们创建了(a,b,c)的联合索引,那么其实相当于创建了(a,b,c)、(a,b)、(a)三个索引,这就是最佳左前缀特性。所以我们在创建联合索引时应该将最常用作限制条件的列放在最左边,一次递减。
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。通过explain可以过得以下信息:
使用方法:explain + sql语句。
执行计划部分字段含义:
id:id相同,执行顺序由上至下。id不同,如果是子查询id序号会递增,id越大优先级越高,越先被执行。id又有相同又有不同时,id相同认为是一组,同一组从上往下,所有组中id大的优先执行
type:显示查询用了哪种类型,类型从好到差依次是:
system>const>eq_ref>ref>range>index>all
possible_keys和key:possible_keys显示可能应用在这张表中的一个或多个索引,查询涉及到的字段若存在索引,则该索引被列出,但不一定被查询实际使用。key实际使用的索引,null代表没有使用
key_len:索引中使用的字节数,长度越短越好
rows:根据表统计信息及索引选用情况,大致估算出需要读取的行数。
所以可以通过explain关键字来测试单列索引和联合索引
问:使用索引一定能提高查询性能吗
答:不一定。
问:哪些情况需要建立索引,哪些情况不需要
答:为经常查询和排序的数据列建立索引
需要:
不需要:
people表中(zipcode,lastname,firstname)构成一个索引
SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';
如果没有使用索引下推技术,则MySQL会通过zipcode='95054'从存储引擎中查询对应的数据,返回到MySQL服务端,
然后MySQL服务端基于lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断数据是否符合条件。
如果使用了索引下推技术,则MYSQL首先会返回符合zipcode='95054'的索引,然后根据lastname LIKE '%etrunia%'
和address LIKE '%Main Street%'来判断索引是否符合条件。如果符合条件,则根据该索引来定位对应的数据,如果不符合,则直接reject掉。
有了索引下推优化,可以在有like条件查询的情况下,减少回表次数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。