##什么是索引
索引是一种文件,一种特殊的文件,索引文件中存放整张表所有记录的引用指针,相当于书本的目录。
- 当没有索引时,数据库查找记录就是便利整张表的记录
- 存在索引时数据库查询先从相应的索引中查找符合条件的项
索引种类
- 聚簇索引
聚簇索引是按照数据存放的物理位置为顺序的
- 非聚簇索引
非聚簇索引,叶级页指向表中的记录,记录的物理顺序与逻辑顺序没有必然联系
聚簇索引相对来说对于多行索引的性能提高比较大,而非聚簇索引对于单行检索比较快
索引的分类
-
普通索引(INDEX) 最基本的索引,无任何限制,MyISAM中默认BTREE类型索引
-
唯一索引(UNIQUE) 与普通索引类似,但唯一索引的索引列的值必须唯一,允许空值,若为组合索引,列值组合必 须唯一
-
全文索引(FULLTEXT) 仅可用于MyISAM引擎的表,在生成全文索引时数据库将会吧文本中出现的所有单词创建为一 份清单,查询操作将会根据这份清单去检索有关的数据记录,但是对于大容量的数据表,生成 全文索引是一种非常消耗时间与存储空间的做法
-
单列索引、多列索引 多个单列索引与与单个多列索引查询效果不同,执行查询时MySQL只能使用一个索引,会从多 个索引中选择一个限制最为严格的索引
-
组合索引(最左前缀) 组合索引时从最左面开始组合,组成一组组索引,例如
ALTER TABLE article ADD INDEX index_time_time(title(50),time(10))
那么此时相当于建立了以下两组索引
- title,time
- title 使用到上面的索引的查询语句如下
SELECT * FROM article WHERE title='测试' AND time=123456789;SELECT * FROM article WHERE title='测试';
不使用上面的索引的查询语句如下
SELECT * FROM article WHERE time=123456789;
索引虽然能提高MySQL的查询速度,但是当我们进行insert、update、delete等写操作时,速度会有所降低,因为在写数据时同样需要更新保存索引文件。
索引的优化
动作描述 | 使用聚集索引 | 使用非聚集索引 |
---|---|---|
经常被分组排序 | 使用 | 使用 |
返回某一范围内的数据 | 使用 | 不使用 |
一个或极少不同值 | 不使用 | 不使用 |
小数目的不同值 | 使用 | 不使用 |
大数目的不同值 | 不使用 | 使用 |
频繁更新的列 | 不使用 | 使用 |
外键列 | 使用 | 使用 |
主键列 | 使用 | 使用 |
频繁修改索引列 | 不使用 | 使用 |
- 使用短索引 对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列, 如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可 以提高查询速度而且可以节省磁盘空间和I/O操作
- 索引不会包含有NULL值的列 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那 么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL
- 索引列排序 MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by 中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引
- like语句操作 一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引
- 不要在列上进行运算 例如:
select * from users where YEAR(adddate)<2007;
将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′;
关于这一点可以围观:一个单引号引发的MYSQL性能损失
- MySQL将所有数据逻辑存放与ibdata1文件中,该文件也被称为表空间,表空间又划分非段(数据段,索引段,回滚段),每个段又划分为区,每个区大小为1M,InnoDB每次最多只能申请4个区,即4M,每个区分为64页,每页16KB,这个大小是固定的
- InnoDB 是面向行的,也意味着数据行将存放与页中,每页最多7992行