索引的含义:它是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对性能的影响就愈发重要。
根据索引的具体用途,MySQL 中的索引在逻辑上分为以下几类
最基本的索引,它没有任何限制,用于加快查询
创建方法:
CREATE INDEX index_name ON table(column(length))
例如我创建的测试表test_table来演示一下创建普通索引
CREATE INDEX name_index ON test_table(name)
创建完毕查看一下:
与前面的普通索引类似,不同的是索引列的值必须唯一,但允许有空值,如果是组合索引,则列值的组合必须唯一。
创建方法:
CREATE UNIQUE INDEX indexName ON table(column(length))
例如:CREATE UNIQUE INDEX age_index on test_table(age)
查看索引:
是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值,一般建表的时候同时创建主键索引。
如:CREATE TABLE `table` ( `id` int(11) NOT NULL AUTO_INCREMENT , `title` char(255) NOT NULL , PRIMARY KEY (`id`) );
指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用,使用组合索引时遵循最左前缀集合
如:CREATE INDEX index_mytable_id_name ON mytable(id,name);
CREATE INDEX zh_index on test_table(age,name)
只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用,使用组合索引时遵循最左前缀集合,这一句话的意思是组合索引有效的化,查询时条件一定要加示例中第一个字段也就是age而且还必须是第一个条件,这样就是优先最左有效
主要用来查找文本中的关键字,而不是直接与索引中的值相比较。Fulltext索引跟其他索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配 ,fulltext索引配合match against操作使用,而不是一般的where语句加like。它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。
创建方法:
CREATE FULLTEXT INDEX index_content ON article(content)
例如测试数据:CREATE FULLTEXT INDEX name_fulltext on test_table(name)
索引的类型和存储引擎有关,每种存储引擎所支持的索引类型不一定完全相同。根据存储方式的不同,MySQL 中常用的索引在物理上分为以下两类
总结一下:
1.1 BTree索引(B-Tree或B+Tree索引),hash索引(为每一行数据精准的建立数字指纹(hash值))通过hash值可以快速的找到数据
1.2 full-index 全文索引
1.3 R-Tree索引(多维索引,应用少,通常是用在Gis系统中)
主键索引含义:主键索引也叫聚簇索引是指主索引文件和数据文件为同一文件,聚簇索引主要用在Innodb存储引擎中。在该索引实现方式中B+Tree的叶子节点上的data就是数据本身,key为主键。在 InnoDB 里,索引B+ Tree的叶子节点存储了整行数据的是主键索引
按图说话:
主键索引叶子节点存储的是数据,所以查询一次就能查询到,查询效果比较好
InnoDB还是会以主键为物理存储
如果除了主键以外又设置了name为索引的话,那么节点就会是name名称,但是name只是会往id上靠,要查询也是查询名称,找name,根据name对应的id再找id索引下的数据。
MyISAM索引使用的是非聚簇索引,非聚簇索引的含义:非聚簇索引就是指B+Tree的叶子节点上的data,并不是数据本身,而是数据存放的地址。也可以说B+Tree的叶子节点存储了主键的值是非聚簇索引。
这里再次引申一个问题,非聚簇索引是所有的情况都查询多次么?
答:其实不是的,当非聚簇索引是覆盖索引的就可以查询一次。
那再引申一个问题,什么是覆盖索引呢?
答:覆盖索引是指一个查询语句的执行只用从索引中就能取得,不必从数据表中读取,也可以称之为实现了索引覆盖。当一条 查询语句符合覆盖索引条件时,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作, 减少I/O提高效率。
如:表covering_index_sample中有一个普通索引 idx_key1_key2(key1,key2)。当我们通过SQL语句:select key2 from covering_index_sample where key1 ='keytest';的时候,就可以通过覆盖索引查询,无需回表。
EXPLAIN select * from innodb_test1 where uid=22
1. 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update、和delete。因为更新表时,不仅要保存数据,还要保存索引文件。
2. 建立索引会占用磁盘空间的索引文件,一般这个问题不太严重,但如果你在大表创建了多种组合索引,索引文件会增长很快。
索引只是提高效率的一个因素,如果有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
如果过多的索引,内存磁盘占用上就比较大,新增也要有重算消耗,那么有一种工具可以帮助删除冗余索引
#索引使用情况
SELECT
object_type,object_schema,object_name,index_name,
count_read,count_fetch, count_insert,
count_update,count_delete
FROM
performance_schema.table_io_waits_summary_by_index_usage
ORDER BY
sum_timer_wait desc;
得到的结果如下图:
在数据进行新增,修改,删除时数据会进行重组,那么就有可能出现空间的浪费,出现碎片。
以上就是MySQL索引介绍的全部内容!希望能够帮助你!下次有时间还会整理Explain执行计划怎么看SQL语句性能的介绍!