说到优化sql的查询,去网上一搜,大多都会提到“要建索引”。但为什么要建索引,建索引的过程究竟做了些什么,则并没有那么直白。
我们常用的索引就两种:聚集索引(clustered index)和非聚集索引(Non-clustered index)。
索引常用的作用有哪些:
- where语句,实际上是查找操作
- order by语句,进行排序
- group by语句,分组总要查找的嘛
- join中,找到匹配的行,实际上也是查找
- 保持数据的唯一性,聚集索引能保证改项的唯一性
一句话说明为什么建索引有这种作用
- 如果无索引,表将以堆表的方式进行组织。如果有索引,数据的组织方式为平衡树(聚集索引和非聚集索引有一定区别),而大家都知道平衡树的查找的复杂度是logn,而进行排序时也比堆要简单的多(因为数据是有序的)
聚集索引和非聚集索引有何区别
- 最大的区别就是索引的节点(树的节点)除了存放索引键值还存放了什么。非聚集索引先在索引中搜索,再根据索引提供的指针去找数据。聚集索引的数据则和索引存放在一起。
- 所以就很好理解一张表只能有一个聚集索引但可以有多个非聚集索引。因为数据只能按照一种方式进行组织,非聚集索引的索引目录有很多则无所谓。
- 对于非聚集索引,这个索引行包含的书签(指向数据的指针)有两种情况。如果表中有聚集索引(数据按聚集索引组织)则非聚集索引的索引行是聚集索引键。如果无聚集索引(heap堆表),则非聚集索引的索引行是一个行标识符(RID),以文件号:页号:槽号定位实际的行。
使用索引时需要注意的地方
- 建索引时要谨慎。对于经常进行where的列建索引是有必要的。但如果where的筛选性不高,如性别这一列一半为男一半为女,则建索引对查找帮助不大,想象一下这棵树是什么样的即可明白。
- like ‘%aaa’不会使用索引,而like ‘aaa%’可以使用索引。这个可以理解。
- 索引当然会影响到插入的性能,因为还要维护索引的树嘛。
不理解的点
- 堆表(heap)和数据结构中的堆有关系吗?因为数据结构中的堆也是一种树。而大量的资料中都会说堆表就是大量无序的数据页。
- 索引的键具体是什么样的?如果以字符串为索引,是进行哈希后做索引吗?还是直接存utf码这种?
- 我对IAM页以及到最底层的数据是怎么存的还有点兴趣,比如如果数据非常大呢,拆成两个数据页还是?
- 这棵树具体是怎么样的还有点迷糊,比如叶子节点什么的?