# 6.3索引优化策略

索引列上不能使用表达式或函数

错误示例

```
select ...... from product
where to_days(out_date)-to_days(current_data)<=30
```

> to\_days()为函数；out\_date为索引列

纠正结果

```
select ...... from product
where out_date<=date_add(current_date,interval 30 day)
```

Mysql的Btree索引对键值大小有限制，大小根据存储引擎的不同有所不同。对于InnoDB存储引擎，Btree索引对键值大小不能超过767个字节；对于MyISAM存储引擎，Btree索引对键值大小不能超过1000个字节

前缀索引和索引列的选择性

CREATE INDEX index\_name ON table(col\_name(n));

索引的选择性是不重复的索引值和表的记录数的比值

联合索引

如何选择索引列的顺序

* 经常会使用到的列优先
* 选择性高的列优先
* 宽带小的列优先

覆盖索引

优点

* 可以优化缓存，减小磁盘的IO操作
* 可以减少随机IO，将随机IO操作变为顺序IO操作
* 可以避免对Innodb主键索引的二次查询
* 可以避免MyISAM表进行系统调用

无法使用覆盖索引的情况

* 存储引擎不支持覆盖索引
* 查询中使用了太多的列
* 使用了双%号的like查询

尝试执行以下命令，观察查询语句所使用的方式：

use sakila

desc film

explain select language\_id from film where language\_id=1\G

explain select \* from film where language\_id=1\G

show create table actor\G

explain select actor\_id,last\_name from actor where last\_name='Joe'\G

使用索引来优化查询

使用索引
