在前一个创建索引中已经大概说了三部分的影响,基本应该注意哪一些。写完上一篇后我感觉有很多地方没有写清楚,所以这篇就是更深入一些的理解索引到底是怎么和数据表关联,怎么快速查询的。
先看一下下面的图,图是描述的在一个表上三个字段建了一个索引的情况,图分成三部分A,B,C。下面慢慢来看这几部分。
A部分,这个是B树的一个缩略图,方便习惯平时的思维。
B部分,这个就是详细的数据排列情况了,举了几个简单的例子,但是大概能看出索引节点里面数据的关系了。这里就像前一篇中想像成group
by 后面的列一样,先排哪个,后排列哪个,那么哪些结构可能会用到这个索引呢?下面我分别列出几个查询,看哪些能用到
1)select * from tb where a>10; 2)select * from tb where b>10; 3)select * from tb where c>‘h‘; 4)select * from tb where b>10 and a>10; 5)select * from tb where b>10 and c>‘h‘; 6)select * from tb where a>10 and c>‘h‘;
B树的查询是从根节点进入的,其实也就是看这些条件哪些能从根节点时入,我们这里不考虑索引扫描的情况,其实SQLServer的索引叶之前还有指针,有时也会用到索引扫描,这里我们只考虑索引查找的情况,假设数据比较大,分部均匀。
根节点的区别是从a开始的,其实我图中数据没有举好,其实在上面两个节点之间也可以有 45,200,x这种类型的数据,所以能用到索引的是用到a条件的1),4),6)其中第4)个位置对换是对逻辑没有影响的。
C部分,这个是最重要的一部分,就是图中有色彩的部分,我为什么经常把图画成这样横过来其实就是为了这个很符合我们的习惯。
看图上,我写了列1,列2 ....列n和页1,页2....页n,这个就和我平时查询表的展示一样,一列一列的,只是而是这样包含所有列的1行或多行,如果一行空间足够大,可以一行就是一个页,平时我们用的多数是多行放到一个列里面。接下来就是说一下查询读取数据的整个过程了。
先是经过A部分可以快速(索引提速就在这里)的查询到所要数据的范围。
再通过索引键去找到数据。
最后读取这些页出来(这里要注意读数据最基本的单位是页,就是你只有一行数据,也会读取一页出来)
上面说了步聚,我们重点来看一下第三步。
1)就算你只读取一行数据,也会读取一整页出来。比如下面查询
select top 1 * from tb where a>10;
这个在最后读取是一个页的数据出来,所以这里SQLServer会有优化的空间。
2)就算你只读取一两列少数数据也会读取一整页出来。比如下面查询
select [列1],[列2] from tb where [列1]>10;
这个在最后读取的是在条件范围内的所有页,也就是也读取了列3到列n的数据。所以这里SQLServer会有优化的空间,SQLServer2012在这里也做了优化,可以创建以列为索引的列存储索引(ColumnStore
Index),当然这个有她的好处,也有不方便的地方,她不能随时更新删除之类的操作,但是他对静态数据的查询是很有效的,比如一个ip库,里面有ip,地名,公司名,还有其它一些列,在这个表上有很多不同的查询,有查地名,有查公司等,这个用这种列存储过引就很有效果,其实这里的例实很有限,你说地名,公司名基本不会占用太大的空间,大概意思到位就行了吧。
最后是总结了,本文主要内容
1,索引B树(图中A部分)
2,索引B树存储结构(图中B部分,带上数据),索引覆盖(那几个查询例子)
3,索引与数据关系,怎么查询的整个过程