标签:相同 范围 pat sql 计划 jpg ons 行记录 依次
索引是满足某种特定查找算法的数据结构。这些数据结构会以某种方式指向数据,从而实现高效查找。
提高了查询速度
降低更新表的速度,因为更新表时,MySQL不仅要保存数据,还要保存索引文件。
建立索引会占用磁盘空间的索引文件。
根据主键pk_column(length)建立索引,不允许重复,不允许空值。
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');
用来建立索引的列的值必须是唯一的,允许空值。
ALTER TABLE 'table_name' ADD UNIQUE INDEX index_name('col');
用普通列构建的索引,没有任何限制。
ALTER TABLE 'table_name' ADD INDEX index_name('col');
用多个列组合构建的索引,这多个列中的值不允许有空值。
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');
遵循“最左前缀”原则,把最常用作为检索或排序的列放在最左,依次递减,组合索引相当于建立了col1,[col1,col2],[col1,col2,col3]三个索引,而col2或者col3是不能使用索引的。
用大文本对象的列构建的索引。
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');
支持空间数据格式。
ALTER TABLE 'table_name' ADD SPATIAL KEY index_name('col');
CREATE INDEX indexName ON tableName(columnName(length));
ALTER table tableName ADD INDEX indexName(columnName)
CREATE TABLE tableName(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
DROP INDEX [indexName] ON tableName;
SHOW INDEX FROM table_name;
平衡多叉树。
B树非叶节点和叶节点都存有数据。
B+树叶子节点存放着所有的数据。
B+树索引在数据库中有一个特点是高扇出性,因此,在数据库中,B+树的高度一般都在2~4层,也就是说查找某一键值的行记录时,最多只需要2~4次IO。
B+树索引可以分为聚集索引(clustered index)和非聚集索引。
MyISAM存储引擎表是堆表,行数据的存储按照插入顺序存放。
非聚集索引叶子节点并不包含行记录的全部数据,而是键值和书签。书签指向数据行的位置。
非聚集索引的存在不影响数据的组织,因此每张表上可以有多个非聚集索引。
InnoDB存储引擎表是索引组织表,即表中数据按照主键顺序存放。(否则会频繁的引起页分裂,严重影响性能。)
聚集索引就是按照每张表的主键构造一棵B+树,因此每张表只能由一个聚集索引。
数据页上存放的是完整的每行的记录,非数据页中存放的仅仅是键值和偏移量。由于聚集索引存储的是数据本身,因此聚集索引会占用更多的空间。
聚集索引的顺序就是数据的物理存储顺序。
聚集索引对于主键的排序查找和范围查找速度非常快。(添加指向相邻叶节点的指针)
MyISAM | InnoDB | |
---|---|---|
索引类型 | 非聚簇 | 聚簇 |
支持事务 | 是 | 否 |
支持表锁 | 是 | 是 |
支持行锁 | 否 | 是(默认) |
支持外键 | 否 | 是 |
支持全文索引 | 是 | 是(5.6以后支持) |
适用操作类型 | 大量select下使用 | 大量insert、delete和update下使用 |
InnoDB:主索引和辅助索引
MyISAM(不支持聚集索引):主索引和辅助索引
EXPLAIN SELECT * FROM `user`
JOIN `post` ON `user`.id = `post`.uid
WHERE user.`created` < '2018-10-01 00:00:00' AND `post`.status = 1;
结果:
id | select _type | table | type | possible _keys | key | key _len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | range | PRIMARY, idx_created | idx_created | 7 | null | 19440 | Using index condition; Using where; Using temporary; Using filesort |
1 | SIMPLE | post | ref | idx_uid, idx_status | idx_uid | 8 | user.id | 1 | Using where |
可能是数据库中的表/视图,也可能是 FROM 中的子查询
create table t1 (a int primary key, b int, c int, d int, e varchar(20));
create index idx_t1_bcd on t1(b, c, d);
insert into t1 values (4,3,1,1,’d’);
insert into t1 values (1,1,1,1,’a’);
insert into t1 values (8,8,8,8,’h’):
insert into t1 values (2,2,2,2,’b’);
insert into t1 values (5,2,3,5,’e’);
insert into t1 values (3,3,2,2,’c’);
insert into t1 values (7,4,5,5,’g’);
insert into t1 values (6,6,4,4,’f’);
idx_t1_bcd索引,首先按照b字段排序,b字段相同,则按照c字段排序,以此类推。记录在索引中按照[b,c,d]排序,但是在堆表上是乱序的,不按照任何字段排序。
考虑以下的一条SQL:
select * from t1 where b >= 2 and b < 8 and c > 1 and d != 4 and e != 'a';
1,此SQL,覆盖索引idx_t1_bcd上的哪个范围?
起始范围:记录[2,2,2]是第一个需要检查的索引项。b >= 2,c > 1
终止范围:记录[8,8,8]是第一个不需要检查的记录,而之前的记录均需要判断。b < 8
2,在确定了查询的起始、终止范围之后,SQL中还有哪些条件可以使用索引idx_t1_bcd过滤?
c > 1 and d != 4
3,在确定了索引中最终能够过滤掉的条件之后,还有哪些条件是索引无法过滤的?
e != ‘a‘
总结出一套放置于所有SQL语句而皆准的where查询条件的提取规则:
MySQL 5.6中引入的ICP(Index Condition Pushdown),是将Index Filter Push Down到索引层面进行过滤的。
在MySQL 5.6之前,并不区分Index Filter与Table Filter,统统将Index First Key与Index Last Key范围内的索引记录,回表读取完整记录,然后返回给MySQL Server层进行过滤。
而在MySQL 5.6之后,Index Filter与Table Filter分离,Index Filter下降到InnoDB的索引层面进行过滤,减少了回表与返回MySQL Server层的记录交互开销,提高了SQL的执行效率。
标签:相同 范围 pat sql 计划 jpg ons 行记录 依次
原文地址:https://www.cnblogs.com/angelica-duhurica/p/11303261.html