14. MySQL索引的设计和使用
1. 使用⚓
创建索引
CREATE [ONLINE|OFFLINE] [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[index_type]
ON tbl_name (index_col_name,...)
[index_option] ...
index_col_name:
col_name [(length)] [ASC | DESC]
index_type:
USING {BTREE | HASH}
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
使用EXPLAIN
查看索引是否被使用:
MariaDB [MYISAM_TEST]> EXPLAIN SELECT * FROM CHILD WHERE PID=4 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: CHILD
type: ref
possible_keys: PARENT_ID
/* 索引被使用 */
key: PARENT_ID
key_len: 3
ref: const
rows: 1
Extra: Using index
1 row in set (0.00 sec)
删除索引:
DROP [ONLINE|OFFLINE] INDEX index_name ON tbl_name
2. 设计原则⚓
- 最适合索引的列是出现在 WHERE 子句中的列,或连接子句中指定的列。
- 使用惟一索引。考虑某列中值的分布。索引的列的基数越大,索引的效果越好。
- 使用短索引。如果对字符串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做。
- 利用最左前缀。 在创建一个 n 列的索引时, 实际是创建了 MySQL 可利用的 n 个索引。多列索引可起几个索引的作用, 因为可利用索引中最左边的列集来匹配行。 这样的列集称为最左前缀。
- 不要过度索引。每个额外的索引都要占用额外的磁盘空间, 并降低写操作的性能。 在修改表的内容时, 索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。
- 对于 InnoDB 存储引擎的表,尽量自己指定主键。InnoDB 表的普通索引都会保存主键的键值,所以主键要尽可能选择较短的数据类型, 可以有效地减少索引的磁盘占用, 提高索引的缓存效果。
3. BTREE 索引与 HASH 索引⚓
MEMORY 存储引擎的表可以选择使用 BTREE 索引或者 HASH 索引, 两种不同类型的索引各有其不同的适用范围。
HASH
索引有一些重要的特征需要在使用的时候特别注意:
- 只用于使用=或<=>(NULL的安全比较)操作符的等式比较(但是很快)。
- 优化器不能使用 HASH 索引来加速 ORDER BY 操作。
- MySQL 不能确定在两个值之间大约有多少行。 如果将一个 MyISAM 表改为 HASH 索 引的 MEMORY 表,会影响一些查询的执行效率。
- 只能使用整个关键字来搜索一行。
而对于 BTREE
索引, 当使用>、 <、 >=、 <=、 BETWEEN、!=或者<>, 或者 LIKE 'pattern' (其
中'pattern'不以通配符开始)操作符时,都可以使用相关列上的索引。
IN
范围查询适用于 BTREE 索引和 HASH 索引:
SELECT * FROM t1 WHERE key_col IN (15,18,20);
InnoDB 和 MyISAM 不支持HASH索引类型,如果指定了使用HASH类型的索引,会被替换为BTREE。
注意:如果需要访问大部分行,顺序读取要快得多,因为此时应避免磁盘搜索。