訪問索引的方法

1.B樹索引的結構

索引分支塊

      包含指向索引分支塊/葉子塊的指針和索引鍵值列

      (這裡指針指的是指向索引分支塊/葉子塊的塊地址RDBA。每個索引分支塊有兩種類型的指針,一種lmc(left most child),一種索引行記錄所記錄的指針。lmc那就是指向最左邊的那個分支塊/葉子塊)

      lmc指向的分支塊/葉子塊的最大值一定<lmc在的那個分支塊的鍵值列的最小值

           簡單來說就是lmc那個地址>它下面最左邊的分支塊/葉子塊的地址

      索引行記錄所記錄的指針指向的分支塊/葉子塊的索引鍵值列的最小值一定>=該行記錄索引鍵值列的值

           例如索引行記錄AD指向的葉子塊都以AD開頭,所以AD<=AD開頭的葉子塊的值,相當於AD指向的葉子塊都是AD開頭

索引葉子塊

      索引鍵值和ROWID

2.常見訪問B樹索引的方法

————————————————————————————————————————————————————————

   (1)索引唯一性掃描(Index Unique Scan)

         針對Unique Index

         where條件是等值

         所以至多返回一條記錄

————————————————————————————————————————————————————————

    (2)索引範圍掃描(Index Range Scan)

          針對Unique Index時,where條件是between,> ,<等

          針對nonUnique Index時,可以=,>,<等

          可能返回多條記錄

—————————————————————————————————————————————————————————

     (3)索引全掃描(Index Full Scan)

            從左至右順序掃描全部葉子塊,單塊讀,不能並行

            因為索引有序,索引結果是按照鍵值列的順序排序。

            使用前提:索引鍵值列只要有一個是not null

SQL> set autotrace on

SQL> select empno ,ename from EMP;   --只有針對empno欄位的索引,這時候無法用到索引,走表全部掃描

     EMPNO ENAME
---------- ----------
      7369 SMITH
      7499 ALLEN
      7521 WARD
      7566 JONES
      7654 MARTIN
      7698 BLAKE
      7782 CLARK
      7788 SCOTT
      7839 KING
      7844 TURNER
      7876 ADAMS

     EMPNO ENAME
---------- ----------
      7900 JAMES
      7902 FORD
      7934 MILLER

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |     |    14 |   140 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| EMP  |    14 |   140 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      3  consistent gets
      0  physical reads
      0  redo size
    837  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed

收集統計信息
SQL> exec dbms_stats.gather_table_stats(OWNNAME=>‘SCOTT‘,tabname=>‘EMP‘,estimate_percent=>100,cascade=>true,method_opt=>‘for all columns size 1‘)
Index Full Scan實驗
實驗一:查詢有唯一索引的列
SQL> select empno from emp;

     EMPNO
----------
      7369
      7499
      7521
      7566
      7654
      7698
      7782
      7788
      7839
      7844
      7876

     EMPNO
----------
      7900
      7902
      7934

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 179099197

---------------------------------------------------------------------------
| Id  | Operation     | Name   | Rows  | Bytes | Cost (%CPU)| Time      |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |    14 |    56 |    1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | PK_EMP |    14 |    56 |    1   (0)| 00:00:01 |
---------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      2  consistent gets
      0  physical reads
      0  redo size
    686  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed
    
empno列上有唯一性索引PK_EMP,所以走的是Index Full Scan

實驗二:在允許為空的列上建索引
SQL> create index idx1_emp on emp(ename,deptno); 

Index created.

SQL> exec dbms_stats.gather_table_stats(OWNNAME=>‘SCOTT‘,tabname=>‘EMP‘,estimate_percent=>100,cascade=>true,method_opt=>‘for all columns size 1‘)

PL/SQL procedure successfully completed.

SQL> select ename,deptno from emp;

ENAME           DEPTNO
---------- ----------
SMITH           20
ALLEN           30
WARD           30
JONES           20
MARTIN           30
BLAKE           30
CLARK           10
SCOTT           20
KING           10
TURNER           30
ADAMS           20

ENAME           DEPTNO
---------- ----------
JAMES           30
FORD           20
MILLER           10

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |     |    14 |   126 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| EMP  |    14 |   126 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      3  consistent gets
      0  physical reads
      0  redo size
    825  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed

實驗結果:ename,deptno的鍵值都是允許為空,在上面列建索引,走TABLE ACCESS FULL

實驗三:修改一個列不允許為空
SQL> alter table emp modify(ename not null);  --把ename改為not null,走的是index full scan

Table altered.

SQL> exec dbms_stats.gather_table_stats(OWNNAME=>‘SCOTT‘,tabname=>‘EMP‘,estimate_percent=>100,cascade=>true,method_opt=>‘for all columns size 1‘)

PL/SQL procedure successfully completed.

SQL> select ename,deptno from emp;

ENAME           DEPTNO
---------- ----------
ADAMS           20
ALLEN           30
BLAKE           30
CLARK           10
FORD           20
JAMES           30
JONES           20
KING           10
MARTIN           30
MILLER           10
SCOTT           20

ENAME           DEPTNO
---------- ----------
SMITH           20
TURNER           30
WARD           30

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1165009684

-----------------------------------------------------------------------------
| Id  | Operation     | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |     14 |    126 |      1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | IDX1_EMP |     14 |    126 |      1   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      2  consistent gets
      0  physical reads
      0  redo size
    825  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed

實驗結果:走Index Full Scan

實驗四:在有很多null欄位的列上建索引

SQL> create index idx2_emp on emp(comm); 

Index created.

SQL> exec dbms_stats.gather_table_stats(OWNNAME=>‘SCOTT‘,tabname=>‘EMP‘,estimate_percent=>100,cascade=>true,method_opt=>‘for all columns size 1‘)

PL/SQL procedure successfully completed.

SQL> select comm from emp;

      COMM
----------

       300
       500

      1400

 

     0

      COMM
----------

 

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |     |    14 |    28 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| EMP  |    14 |    28 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      3  consistent gets
      0  physical reads
      0  redo size
    645  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed
    
實驗結果:走TABLE ACCESS FULL    ,結果也體現出包含了那些null的結果

總結:在允許為null的列上建立索引,還是會走TABLE ACCESS FULL。因為欄位允許為null,而null並不會存儲索引的。只有走全錶掃描,才能體現值得完整性。

Index Full Scan掃描結果是有序的,順序按照索引鍵值列的順序
Index Full Scan必須滿足條件:目標索引至少有一個索引鍵值列的屬性為not null.

——————————————————————————————————————————————————————————
(4)索引快速全掃描(Index Fast Full Scan)
(1)僅適用于CBO
(2)使用多塊讀,可以並行
(3)結果不一定有序
其他和index full scan一樣咯
SQL> select /*+index_ffs(emp IDX1_EMP) */ename,deptno from emp;

ENAME           DEPTNO
---------- ----------
ADAMS           20
ALLEN           30
BLAKE           30
CLARK           10
FORD           20
JAMES           30
JONES           20
KING           10
MARTIN           30
MILLER           10
SCOTT           20

ENAME           DEPTNO
---------- ----------
SMITH           20
TURNER           30
WARD           30

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3993716296

---------------------------------------------------------------------------------
| Id  | Operation         | Name    | Rows    | Bytes | Cost (%CPU)| Time    |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        |    14 |   126 |     2   (0)| 00:00:01 |
|   1 |  INDEX FAST FULL SCAN| IDX1_EMP |    14 |   126 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
      4  consistent gets
      0  physical reads
      0  redo size
    825  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
     14  rows processed

————————————————————————————————————————————————————————

(5)索引跳躍掃描(Index Skip Scan)
簡單點來講就是你在ename,deptno兩個欄位建了索引,但是我們查詢的時候只用了deptno(沒有使用該索引的前導列)
但是僅僅使用于那些前導列的distinct值很少,後續非前導列選擇性又非常好的情景。
SQL> select ename from emp where deptno>20;

ENAME
----------
ALLEN
BLAKE
JAMES
MARTIN
TURNER
WARD

6 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3860167482

-----------------------------------------------------------------------------
| Id  | Operation     | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |      7 |     63 |      1   (0)| 00:00:01 |
|*  1 |  INDEX SKIP SCAN | IDX1_EMP |      7 |     63 |      1   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("DEPTNO">20)
       filter("DEPTNO">20)

Statistics
----------------------------------------------------------
      1  recursive calls
      0  db block gets
      2  consistent gets
      0  physical reads
      0  redo size
    628  bytes sent via SQL*Net to client
    523  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      6  rows processed

时间: 2024-10-14 13:36:02

訪問索引的方法的相关文章

啟用SSH強化核心層,分布層交換機訪問安全

問題陳述 原核心層,分布層交換機遠程訪問配置為Telnet方式.因Telnet傳輸過程使用明文方式,在日趨嚴峻的安全威脅下,存在用戶名和密碼被截獲的高風險.一旦發生此類事件,將會導致整個網絡控制權被奪取. 解決方案 SSH(Secure Shell)使用加密的傳輸方式,可以有效解決被直接嗅探的可能.為平衡加密速度和安全強度,我們建議把加密長度設置為1024位.同時,為保證在radius失效時可以登錄交換機,配置了備用的本地認證方式. 各類交換機型號 目前公司環境,核心層和分佈層交換機主要有如下型

mongoose中给字段添加索引的方法

mongoose中给字段添加索引的方法有两种,一种通过在定义schema的时候配置,如: 1 var animalSchema = new Schema({ 2 name: String, 3 type: String, 4 tags: { type: [String], index: true } 另一种通过index方法添加索引,如给name和type字段添加索引(1和-1分别表示升序索引和降序索引): animalSchema.index({ name: 1, type: -1 });

索引访问方法及索引优化

要了解索引访问方法,首先要知道索引的结构. 1.表和索引的结构  页 页是sql server存储数据的基本单位,大小为8kb,可以存储表数据.索引数据.执行计划数据.分配位图.可用空间信息.页是sql server可以读写的最小I/O单位.即便是读取一行数据,它也要把整个页加载到缓存并从缓存中读取数据. 区 区是由8个连续页组成的分配单元. 堆 堆是指不含聚集索引的表,它的数据不按任何顺序进行存储. 联系一个堆中的数据的唯一结构是被称为索引分配映射(IAM)的一个位图页,当扫描对象时,SQl

Nginx支持https訪問

Nginx支持https訪問 # yum -y install openssl openssl-devel 然后就是自己颁发证书给自己 # cd /usr/local/nginx/conf 1.創建帶密鑰口令的私鑰key # openssl genrsa -des3 -out server.key 1024 2.創建證書申請文件csr # openssl req -new -key server.key -out server.csr 3.清除私鑰的口令,重新生成不帶密鑰的key(不清除口令,重

apache支持https訪問

apache支持https訪問 创建默认的证书:安装ssl模块# yum –y install mod_ssl重启apache服务# service httpd restart手动创建证书:安装 openssl# yum –y install openssl openssl-devel创建私钥# openssl genrsa –out server.key1024用私钥server.key文件生成证书签署请求CSR# openssl req -new -key server.key -out s

访问索引的方法

首先要说明一点,以下提到是oracle数据库最常用的B树索引,oracle数据其他类型的索引暂不考虑,B树索引就好像一棵倒长的树,它包含两种类型的数据块,一种是索引分支块,另一种是索引叶子块. 索引分支块包含指向响应索引分支块/叶子块的指针和索引键值列(这里的指针是指相关分支块/叶子块的块地址RDBA,每个索引分支块都有两种类型的指针,一种是lmc,另一种是索引分支块的索引行记录的指针.lmc是left Most Child的缩写,每个索引分支块都只有一个lmc,这个Imc指向的分支块/叶子块中

创建索引的方法有两种

创建索引的方法有两种:创建表的同时创建索引,在已有表上创建索引. 方法一:创建表的同时创建索引. 使用这种方法创建索引时,可以一次性地创建一个表的多个索引(例如唯一性索引.普通索引.复合索引等),其语法格式与创建的语法格式基本相同(注意粗体字部分的代码). Create  table 表名( 字段名1数据类型 [约束条件] 字段名字2   数据类型 [约束条件] - [unique][fulltext] index [索引名](字段名[(长度)] [asc|desc]) )engine=存储引擎

C# 索引器方法

使用索引操作 [] 访问包含在一个标准数组中的各个子项. 定义:把能使用索引操作符 [] 访问子项的方法称为索引器方法 1.自定义索引器方法(this): public class PeopleCollection : IEnumerable { private ArrayList arPeople= new ArrayList(); // 类的自定义索引器 public Person this [int index] // 除了多个this关键字外,和属性声明很相似 { get{ return

【Windows Server 2019】文件共享,應該不支持 Everyone 訪問

Windows Server 2019 文件共享 選擇共享的用戶 everyone 當客戶端去訪問Windows2019服務器的共享文件夾的時候,會不停地提示你輸入用戶名與密碼,就算是Administraotrs組別的成員都是無法訪問,我不知道是不是BUG,或者說安全設定,但是現在的結果告訴你的是:無法訪問. 解決的辦法是刪除Everyone,添加一個制定賬號,應該組別也是可以的,結果有待測試. 原文地址:http://blog.51cto.com/happynews/2159519