如果数据库不建索引会怎么样?
假设表中有三个字段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’的时候,行中其他列的数据也可以获取到。
常见的索引种类:
- 普通索引: 即针对数据库表中某个字段创建索引
- 唯一索引: 与普通索引类似,不同的就是:MySQL 数据库索引列的值必须唯一,但允许有空值
- 主键索引: 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引
- 组合索引: 为了进一步提高 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’