标签:字符串 等于 临时 线程 select 而不是 uniq image sql语句
【官方定义】索引(Index) 是帮助 MySQL 高效获取数据的数据结构。
在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向) 数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
下图为一种可能的索引方式示例。为了加快 Col2 的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。
【小结】索引本质是数据结构,可以简单理解为“排好序的快速查找数据结构”。
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。
我们平时所说的索引,如果没有特别指明,都是指 B 树(多路搜索树,不一定是二叉的)。其中,聚集索引、次要索引、覆盖索引、复合索引、前缀索引、唯一索引均是默认使用 B+ 树索引,统称“索引”。当然,除了 B+ 树这种类型的索引之外,还有哈希索引(hash index) 等。
优势:
劣势:
索引是在 MySQL 的存储引擎层中实现的,而不是在服务器层实现的。所以每种存储引擎的索引都不一定完全相同,
也不是所有的存储引擎都支持所有的索引类型的。MySQL 目前提供了以下 4 种索引:
我们平常所说的索引,如果没有特别指明,都是指 B+ 树(多路搜索树,并不一定是二叉的)结构组织的索引。其中
聚集索引、复合索引、前缀索引、唯一索引默认都是使用 B+tree 索引,统称为 "索引"。
BTree 又叫“多路平衡搜索树”,一颗 m 叉的 BTree 特性如下:
以 5 叉 BTree 为例,key 的数量:公式推导 [ceil(m/2)-1] <= n <= m-1
。所以 2 <= n <=4,而当 n>4 时,中间节点分裂到父节点,两边节点分裂。
现以插入 C N G A H E K Q M F W L T Z D P R X Y S 数据为例,演变过程如下:
到此,该 BTREE 树就已经构建完成了, BTREE 树和二叉树相比, 查询数据的效率更高, 因为对于相同的数据量来说,BTREE 的层级结构比二叉树小,因此搜索速度快。
B+Tree 为 BTree 的变种,B+Tree 与 BTree 的区别为:
由于 B+Tree 只有叶子节点保存 key 信息,查询任何 key 都要从 root 走到叶子。所以 B+Tree 的查询效率更加稳定。
B 和 B+ 的区别:
思考:为什么说 B+ 树比 B 树更适合实际应用中操作系统的文件索引和数据库索引?
MySQL 索引数据结构对经典的 B+Tree 进行了优化。在原 B+Tree 的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的 B+Tree,提高区间访问的性能。
MySQL 中的 B+Tree 索引结构示意图:
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。术语‘聚簇’表示数据行和相邻的键值聚簇的存储在一起。如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。
聚簇索引的好处:
按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,所以节省了大量的 IO 操作。
聚簇索引的限制:
即一个索引只包含单个列,一个表可以有多个单列索引。
CREATE TABLE customer (
id INT(10) UNSIGNED AUTO_INCREMENT,
customer_no VARCHAR(200),
customer_name VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name)
);
CREATE INDEX idx_customer_name ON customer(customer_name);
DROP INDEX idx_customer_name ON customer;
索引列的值必须唯一,但允许有空值,NULL 可出现多次。
CREATE TABLE customer (
id INT(10) UNSIGNED AUTO_INCREMENT,
customer_no VARCHAR(200),
customer_name VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name)
UNIQUE (customer_no)
);
CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);
DROP INDEX idx_customer_no ON customer;
设定为主键后数据库会自动建立索引,innodb 为聚簇索引。
CREATE TABLE customer (
id INT(10) UNSIGNED AUTO_INCREMENT,
customer_no VARCHAR(200),
customer_name VARCHAR(200),
PRIMARY KEY(id),
);
ALTER TABLE customer ADD PRIMARY KEY customer(customer_no);
ALTER TABLE customer DROP PRIMARY KEY;
即一个索引包含多个列。
CREATE TABLE customer (
id INT(10) UNSIGNED AUTO_INCREMENT,
customer_no VARCHAR(200),
customer_name VARCHAR(200),
PRIMARY KEY(id),
KEY (customer_name)
UNIQUE (customer_no)
KEY (customer_no, customer_name)
);
CREATE INDEX idx_no_name ON customer(customer_no, customer_name);
DROP INDEX idx_no_name ON customer;
CREATE [UNIQUE] INDEX [indexName] ON table_name(column)
DROP INDEX [indexName] ON table_name
SHOW INDEX FROM table_name\G
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)
该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。ALTER TABLE tbl_name ADD UNIQUE index_name (column_list)
该语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。ALTER TABLE tbl_name ADD INDEX index_name (column_list)
添加普通索引,索引值可出现多次。ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list)
该语句指定了索引为 FULLTEXT,用于全文索引。索引的设计可以遵循一些已有的原则,创建索引的时候请尽量考虑符合这些原则,便于提升索引的使用效率,更高效的使用索引。
哪些情况需要创建索引?
哪些情况不要创建索引?
索引的选择性是指索引列中不同的值的数目与表中记录数的比。如果一个表中有 2000 条记录,表索引列有 1980 个不同的值,那么这个索引的选择性就是 1980/2000=0.99。一个索引的选择性越接近于 1,这个索引的效率就越高。
EXPLAIN + SQL语句
select 查询的序列号,包含一组数字,表示查询中执行 select 子句或操作表的顺序。
查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。
对应行正在访问哪一个表,表名或者别名,可能是临时表或者 union 合并结果集。
表示 MySQL 在表中找到所需行的方式,又称“访问类型”,是较为重要的一个指标。
结果值从最好到最坏依次是:null > system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range(尽量保证) > index > ALL
常用的有:system > const > eq_ref > ref > range > index > all。
between、<、>、in
等的查询,这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束语另一点,不用扫描全部索引。
[possible_keys] 显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。[key] 表示实际使用的索引;如果为 NULL,则没有使用索引。
查询中若使用了覆盖索引,即索引关联字段和查询的 select 字段重叠的情况:
[key_len] 表示 !WHERE! 后面的筛选条件命中索引的长度,命中索引所关联的字段越多,长度越长。可通过该列计算查询中使用的索引的长度。
字符集会影响索引长度、数据的存储空间,为列选择合适的字符集;变长字段需要额外的 2 个字节,固定长度字段不需要额外的字节。而 NULL 都需要 1 个字节的额外空间,所以以前有个说法:索引字段最好不要为 NULL,因为 NULL 让统计更加复杂,并且需要额外一个字节的存储空间。
ken_len 显示的值为索引字段的最大可能长度,并非实际使用长度,即 key_len 是根据表定义计算而得,不是通过表内检索出的。
显示索引的哪一列被使用了,即哪些列或常量(const) 被用于查找索引列上的值。
根据表统计信息及索引选用情况,大致估算出找到所需的记录需要要读取的行数。
包含不适合在其他列中显示但十分重要的额外信息
标签:字符串 等于 临时 线程 select 而不是 uniq image sql语句
原文地址:https://www.cnblogs.com/liujiaqi1101/p/13930972.html