表访问方式
对于oracle数据库来说:
1、数据库里面就是一张一张的表,表里是一行行的数据
2、最核心的工作就是用户往数据库里存表
3、修改表里的数据,删除数据
4、访问表里的数据
对于oracle数据库来说,最核心的就是对表的操作(访问表)
表的两种访问方式
以select为例,看select如何从表中取数据?
从表里取数据可以有两种方式:
1、全表扫描
2、走索引
1、全表扫描(filter)
以SQL语句:select name from t where id = 5;为例:
就是把t表里面的数据,从头到尾,全部访问一遍,每访问一行,都用id = 5去过滤(filter)一下,假设过滤了3行出来
因为有100万行,只取了3行出来,效率就很低
2、走索引(access)
索引
图解:
在表的某个列上建索引,比如:在id列上建索引:
1、就是把这个id列拿出来,把这个id列拿出来的同时,也把每个id对应的行的地址拿出来了,地址这一列叫做rowid;
2、把id列拿出来以后,进行排序(sort);
排序有什么好处呢?
当查找条件id = 5时,在排好序的id列里面找,找到id = 5时,后面一个是6,就不往后面找了,因为后面不可能有5了,终点好确定,但是起点又不好确定了;这时候,如果id = 5在最后一行,就要把所有的扫描一遍,这样就不好了;
3、所以呢,我们在id这个列上建一棵树,我们要找id = 5的,就从根,找到其中一个分支(1~5的分支),然后再找到id = 5
走索引,就是通过索引来访问表(access),通过索引来访问表有两块成本:1、索引访问的成本,2、通过索引来访问表的成本
索引的特点:
1、有树
2、叶子是排好序的
3、带着rowid
现在感觉走索引效果好,其实呢,有时候全表扫描好,有时候走索引好,大体上有一个原则(这只是一个经验值,具体情况要具体对待):
例:对于SQL语句:select name from t where id = 5;来说:
根据where id = 5这个条件,一般情况:
1、假设要访问的数据 <5%,t表里有100万行数据,id = 5的数据有100行,100/100万 <5%,这时候走索引效果最好;
2、然后呢,假设要访问的数据在5%~20%之间,100万行数据要取10万行,取10%的数据,这时候就要具体情况具体对待了;
3、再有,假设要访问的数据 >20%,100万行数据要取50万行,这时候全表扫面更好一些
集群因子(cluster factor)
集群因子反映的是:这个表在id列上的一个有序度:如果这个表在存储的时候,是按照id列的顺序来存储的,它的集群因子是最小的;如果这个表存储的时候,没有按id列的顺序来存储的,杂乱无章的,它的集群因子就很大了
集群因子还反映了:通过索引来访问表的成本,集群因子小的话,通过索引来访问表的成本就很低;集群因子很大的话,通过索引来访问表的成本就很高
集群因子的特点:
1、对每一个索引,都有一个集群因子
2、集群因子是一个数字
3、集群因子,最小等于表的块数
4、集群因子,最大等于索引的行数
怎么计算集群因子呢?
图解:
1、在数据库里面存储着表,表里有一行行的数据,其实,表的实际存储情况是:表存储在一个一个块里面,块有块的地址,行有行的地址;
2、把索引的id列扫描一遍,索引的第一行,集群因子等于0,根据rowid对应块里面的一行;然后,索引的第二行的rowid对应的行和索引第一行对应的行在同一个块里,集群因子再加上0;再然后,索引的第三行的rowid对应的行和索引第二行对应的行不在同一个块里,集群因子再加上1;以此类推......
3、集群因子也就是,把索引扫描一遍,然后比较下一行跟上一行所对应的行在不在同一个块里;如果,索引里面的下一行和上一行所对应的行在同一个块里,集群因子加上0;如果,索引里面的下一行和上一行所对应的行不在同一个块里,集群因子加上1;
4、假设id索引有100万行,表有10万个块,对于id列这个索引来说,它的集群因子:最小 = 10万,最大 = 100万,也就是集群因子,最小等于表的块数,最大等于索引的行数
计算访问表的成本
图解:
假设,SQL语句:select name from t where id = 5;中的t表100万行,id = 5的数据有1万行,这就是取1%的数据,这时候走索引效果更好,那么走索引的成本是多少呢?
1、根到分支再到索引,索引里面id = 5的数据有1万行,索引里面每一个块里有1000行,这就有10个块
2、然后呢,这个表的集群因子非常高,等于表的行数,这里取1万行,每一行对应一个块;
全表扫描的成本是多少呢?
假设表里有100万行数据,一个块里面有100行,那就是1万个块,这相对于走索引的10012个块来说,反而相对好一点
如果,假设集群因子很低呢?
走索引的成本是多少呢?1、索引访问的成本12个块是不变的,通过索引来访问表,这个表一共有10000个块,取1%的数据,通过索引来访问表的成本就是1/100*10000 = 100个块,所以最后需要的成本是112个块
对于全表扫描,还是需要1万个块,这时候走索引是最好的
记住:索引来访问表,这个索引的访问效率到底高不高呢,取决于几个点:
1、在索引里面到底返回多少行,比如:id = 5在索引里返回多少行,如果返回一行的话,效率就很好;
2、集群因子
通过索引来访问表,这个索引到底好不好,通过索引来访问表的效率高不高,取决于:
1、索引的选择性:t表有100万行,就返回1行,这时候就说索引的选择性很高,这个索引好
索引的选择性很高:唯一值的数量/索引的行数 = 100%
2、集群因子