如果数据库不建索引会怎么样?
假设表中有三个字段Name,Age,Address,如果我们执行SELECT * FROM Employee WHERE Name=‘lucky’,数据库会全表扫描,去查询Name=‘lucky’,如果找到了还会继续扫描下一行,
因为表中也有可能会有另外一条记录Name=‘lucky’。表中的几万条记录都要去查询,恐怖!!
索引的出现
MySQL 数据库存储数据最终是以文件的形式存储到硬盘的。我们在程序中使用的时候肯定要把磁盘文件中的数据读到内存中。磁盘机械的读取对于磁盘 IO 是非常高昂的操作。所以产生了索引,索引的存在是为了提高查询效率,减低IO。
什么是索引

排好序的快速查找的B+树的数据结构,说的简单一点索引是一种数据结构,索引就像相当于新华字典的目录,建立索引,可以加快数据的检索速度,降低数据库的IO成本,但索引也会带来一些去缺点:索引如果太大被占用磁盘的空间,并且对于数据的增删改操作,需要动态的维护索引。
索引里放了什么?
索引(对于myisam来说)是创建在表中的某列上,索引中保存了该列的所有数据,索引并不保存其他列的数据。例如我们Name列上创建了索引,同一张表的其他列的数据不会被保存到索引中。
索引除了保存列值之外,还保存了与该列值关联的行在表中的位置信息,即保存了关联行在表中的位置的指针。
因此,Name索引中的值看起来大概是 (‘lucky’, 0x99456),0x99456就是“'lucky”这一行在磁盘上的存储地址(指针)。所以当我们检索Name='lucky’的时候,行中其他列的数据也可以获取到。
常见的索引种类:

  1. 普通索引: 即针对数据库表中某个字段创建索引
  2. 唯一索引: 与普通索引类似,不同的就是:MySQL 数据库索引列的值必须唯一,但允许有空值
  3. 主键索引: 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引
  4. 组合索引: 为了进一步提高 select的效率,就要考虑建立组合索引。 即将数据库表中的多个字段联合起来作为一个组合索引

索引失效的情况

  • 不符合最佳左前缀法则
    过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。
    sql语句如下:
    SELECT * FROM emp WHERE emp.age=30 and deptid=4 AND emp.name = ‘abcd’
    必须建立索引如下:
    CREATE INDEX idx_age_deptid_name ON emp(age,deptid,name)
  • 模糊查询%like
    如下sql语句索引会失效:
    SELECT SQL_NO_CACHE * FROM emp WHERE emp.name LIKE ‘%abc’
  • where条件后中有is not null,但is null是可以使用索引的
    如下sql语句索引会失效:
    SELECT * FROM emp WHERE age IS NOT NULL
  • where条件后的列做运算
    如下sql语句索引会失效:
    SELECT SQL_NO_CACHE * FROM emp WHERE LEFT(emp.name,3) = ‘abc’
  • 字符串不加单引号
  • where条件后中使用不等于(!= 或者<>)的时候
    如下sql语句索引会失效:
    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.name <> ‘abc’