索引是关系型数据库给数据库表中一列或多列的值排序后的存储结构。SQL的主流存储结构是B+树以及Hash结构,聚集索引和非聚集索引用的是B+树索引。
mysql索引:唯一索引,主键(聚集)索引,非聚集索引,全文索引
聚集索引
聚集(clustered)索引也叫聚簇索引
聚集索引:数据行的物理顺序与列值(一般是主键的那一列)的逻辑行顺序相同,一个表中只能拥有一个聚集索引
创建聚集索引:
如果不创建索引,系统会自动创建一个隐含列作为表的聚集索引
1,创建表的时候指定主键(mysql的主键就是聚集索引)
create table t1 (
id int primary key,
name char(30)
)
2,创建表后创建聚集索引
alter table tb_name add primary key(id); //Mysql
最好在创建表的时候创建聚集索引(主键),由于聚集索引的物理顺序上的特性,因此如果在在上面创建索引时,会根据索引列的排序移动全部数据行上面的顺序,会非常耗费时间和性能
非聚集索引
非聚集索引:该索引中索引的逻辑顺序与磁盘上的物理存储顺序不同,一个表可以拥有多个非聚集索引
按照定义:其实除了聚集索引(即主键)其他的索引都是非聚集索引。为了划分更细,分为了 普通索引、全文索引、唯一索引
非聚集索引的二次查询问题:非聚集索引叶节点仍然是索引节点,只是有一个指针指向对应的数据块,此如果使用非聚集索引查询,而查询列中包含了其他索引没有覆盖的列,那么他还要进行第二次查询,查询节点上对应数据行的数据
id值clustered(聚集索引即主键),username是非聚集索引
select id,username from t1 where username='小明'; //此查询不需要进行二次查询,直接可以从非聚集索引节点里面就可以获取查询列的数据
select id,username,score from t1 where username = '小明'; //此查询就需要进行二次查询去获取原数据行的score
如何解决非聚集索引的二次查询的问题
复合索引(覆盖索引)
建立两列以上的索引,即可查询复合索引里的列的数据而不需要回表二次查询,如index(col1,col2)
select col1,col2 from tb where col1 = '213'
要注意使用复合索引要符合最左侧索引的原则,也就是查询条件的时候如果where条件没有最左侧的一列到多列,索引就不会起作用。
1,使用聚集(主键)索引比非聚集索引效率高,如果需要频繁改变聚集索引的值,写入性能并不高,因为需要移动对应数据的物理位置
2,非聚集索引在查询的时候可以的话就避免二次查询,这样性能会大幅提升
3,不是所有的表都适合创建索引,只有数据量大的表才适合创建索引,且建立在选择性高的列上面性能会更好