MySQL基础学习笔记之——索引的设计和使用

索引的设计和使用

1、索引概述

所有的 MySQL 列类型都可以被索引,对相关列使用索引是提高 SELECT 操作性能的最佳途径。根据存储引擎可以定义的每个表的最大索引数和最大索引长度,每种存储引擎对每个表至少支持 16 个索引,总索引长度至少为 256 字节。

MyISAM 和 InnoDB 存储引擎的表默认创建的都是 BTREE 索引。MySQL 目前还不支持函数索引,但是支持前缀索引,即对索引字段的前 N 个字符创建索引。前缀索引的长度跟存储引擎相关,对于 MyISAM 存储引擎的表,索引的前缀长度可以达到 1000 字节,而对于 InnoDB 存储引擎的表,索引的前缀长度最长为 767 字节。

MySQL 中还支持全文本索引,该索引可以用于全文搜索。但是当前最新版本中只有 MyISAM 存储引擎支持 FULLTEXT 索引,并且只限于 CHAR、VARCHAR 和 TEXT 列。索引总是对整个列进行的,不支持局域索引。

也可以为空间列类型创建索引,但是只有 MyISAM 存储索引支持空间类型索引,且索引的字段必须是非空的。

默认情况下,MEMORY 存储引擎使用 HASH 索引,但也支持 BTREE 索引

索引在创建表的时候可以同时创建,也可以随时增加新的索引。创建新索引的语法为:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[USING index_type]
ON tbl_name(index_col_name,...)

index_col_name:
	col_name[(length)][ASC|DESC]

也可以使用 ALTER TABLE 的语法来增加索引,语法与 CREATE INDEX 类似,例如:要为 city 表创建 10 个字节的前缀索引:

mysql> create index cityname on city(city(10));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

索引删除的语法为:

DROP INDEX index_name ON tbl_name
mysql> drop index cityname on city;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

2、设计索引的原则

  • 搜索的索引列,不一定是所要选择的列。换句话说,最合适索引的列是出现在 WHERE 子句中的列,或者连接子句中的列,而不是出现在 SELECT 关键字后的选择列表中的列。
  • 使用唯一索引。考虑某列中值的分布,索引的列的基数越大,索引效果越好。
  • 使用短索引。
  • 利用最左前缀。
  • 不要过度索引。
  • 对于 InnoDB 存储引擎的表,记录默认会按照一定的顺序保存,如果有明确定义的主键,则按照主键顺序保存。如果没有主键,但是有唯一索引,那么就是按照唯一索引的顺序保存。如果既没有主键也没有唯一索引,那么表中会自动生成一个内部列,按照这个列的顺序保存。

3、BTREE 索引与 HASH 索引

MEMORY 存储引擎的表可以选择使用 BTREE 索引或者 HASH 索引,两种不同类型的索引各有其不同的使用范围。HASH 索引有一些重要的特性需要在使用的时候特别注意:

  • 只用于使用 = 或 <=> 操作符的等式比较;
  • 优化器不能使用 HASH 索引来加速 ORDER BY 操纵;
  • MySQL 不能确定在两个值之间大约有多少行。如果将一个 MyISAM 表改为 HASH 索引的 MEMORY 表,会影响一些查询的执行效率;
  • 只能使用整个关键字来搜索一行。

而对于 BTREE 索引,当使用 >、<、>=、<=、BETWEEN、!= 或者 <>,或者 LIKE ‘pattern’ 操作符时,都可以使用相关列上的索引。

下列范围查询适用于 BTREE 索引和 HASH 索引:

SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,20);

下列范围查询只适用于 BTREE 索引:

SELECT * FROM t1 WHERE key_col > 1 AND key_col < 10;
SELECT * FROM t1 WHERE key_col LIKE 'ab%' OR key_col BETWEEN 'lisa' AND 'simon';

例如,创建一个和 city 表完全相同的 MEMORY 存储引擎的表 city_memory:

mysql> CREATE TABLE city_memory( 
	 > city_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, 
	 > city VARCHAR(50) NOT NULL,
     > country_id SMALLINT UNSIGNED NOT NULL,
     > last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     > PRIMARY KEY(city_id), KEY idx_fk_country_id (country_id) )ENGINE=Memory DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.00 sec)

当使用 Memory 表时,如果是默认创建的 HASH 索引,就要注意 SQL 语句的编写,确保可以使用上索引,如果一定要使用范围查询,那么在创建索引时,就应该选择创建成 BTREE 索引。


4、小结

索引用于快速找出在某个列中有一特定值的行。如果不使用索引,MySQL 必须从第 1 条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL 能快速到达一个位置去搜寻数据文件的中间,没有必要看所有数据。

大多数 MySQL 索引(如 PRIMARY KEY、UNIQUE、INDEX 和 FULLTEXT 等)在 BTREE 中存储。只是空间类型的索引使用 BTREE,并且 MEMORY 表还支持 HASH 索引。

猜你喜欢

转载自blog.csdn.net/qq_36879493/article/details/108541467