久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何進行null與index的分析

192次閱讀
沒有評論

共計 5248 個字符,預計需要花費 14 分鐘才能閱讀完成。

這期內容當中丸趣 TV 小編將會給大家帶來有關如何進行 null 與 index 的分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

今天在測試過程中遇到一問題, SQL 該走 Index 的, 沒走. 加 index hint 也不行. 描述如下:

1. 建立測試表
create table t1
as
select object_id, object_name from dba_objects;

2. 在 object_name 列上建立 b -tree index
create index idx_t1_name on t1(object_name);

3. 如果我是 select object_name from t1, 按理說 CBO 應該會選擇走 Index scan. 但奇怪的是結果走的 full table scan.
SQL set autotrace trace exp
SQL select object_name from t1;

Execution Plan
———————————————————-
Plan hash value: 3617692013

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 50934 | 3282K| 57 (2)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T1 | 50934 | 3282K| 57 (2)| 00:00:01 |
————————————————————————–

Note
—–
– dynamic sampling used for this statement

[@more@]
3. 使用 index hint 想強行走 Index, 結果還是 full table scan. 我就奇怪了. hint 咋個不起做用呢? 郁悶.
SQL select /*+ index(t1, idx_t1_name) */ object_name from t1;

Execution Plan
———————————————————-
Plan hash value: 3617692013

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 50934 | 3282K| 57 (2)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T1 | 50934 | 3282K| 57 (2)| 00:00:01 |
————————————————————————–

Note
—–
– dynamic sampling used for this statement

4. 偶然看了下表結構
SQL desc t1
Name Null? Type
—————————————– ——– —————————-
OBJECT_ID NUMBER
OBJECT_NAME VARCHAR2(128)

NULL 列引起我的注意. OBJECT_NAME 可以為 null !! 而在 oracle 中單個列上建 b -tree Index, null 是不會存進 Index 的 (復合索引可以, 只要整個 Index columns 不為 null). 那就是說如果有些行的 object_name 是 null, 那走 Index 取值不是會丟掉 object_name 為 null 的行. 那如果我讓 object_name not null 呢?

SQL alter table t1 modify object_name not null;

Table altered.

SQL desc t1
Name Null? Type
—————————————– ——– —————————-
OBJECT_ID NUMBER
OBJECT_NAME NOT NULL VARCHAR2(128)

再試一試
SQL select object_name from t1;

Execution Plan
———————————————————-
Plan hash value: 3617692013

————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
————————————————————————–
| 0 | SELECT STATEMENT | | 50934 | 3282K| 57 (2)| 00:00:01 |
| 1 | TABLE ACCESS FULL| T1 | 50934 | 3282K| 57 (2)| 00:00:01 |
————————————————————————–

結果還是 full table scan : (

試試用 hint
SQL select /*+ index(t1, idx_t1_name) */ object_name from t1;

Execution Plan
———————————————————- 
Plan hash value: 1352742509 

——————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————–
| 0 | SELECT STATEMENT | | 50934 | 3282K| 264 (1)| 00:00:04 |
| 1 | INDEX FULL SCAN | IDX_T1_NAME | 50934 | 3282K| 264 (1)| 00:00:04 |

這回 hint 起作用了. 這說明并不是 Hint 失效, 只是滿足走 Index 的條件一開始沒有具備. 看來 null 是個潛在殺手, 得小心防范. 
現在強走 index 是 ok 了. 但, 是什么東西會影響 CBO 的判斷不走 Index 呢? 想到統計信息可能會是原因之一, 于是查看了一下.

SQL select index_name, LAST_ANALYZED from user_indexes;
INDEX_NAME LAST_ANALYZED 
—————————————————————————————— ————— 
IDX_T1_NAME 01-MAR-18

SQL select table_name, LAST_ANALYZED from user_tables;

TABLE_NAME LAST_ANALYZED 
—————————————————————————————— ————— 
T1

看到剛建的表沒有做過統計. 于是 go to analyze table, 結果如下:

SQL exec dbms_stats.gather_table_stats(TEST , T1

PL/SQL procedure successfully completed.

SQL select table_name, LAST_ANALYZED from user_tables;

TABLE_NAME LAST_ANALYZED 
—————————————————————————————— ————— 
T1 01-MAR-18

再來看看執行結果有沒有變化:
SQL select object_name from t1;

Execution Plan
———————————————————- 
Plan hash value: 222950081

———————————————————————————— 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 
———————————————————————————— 
| 0 | SELECT STATEMENT | | 49917 | 1218K| 57 (2)| 00:00:01 | 
| 1 | INDEX FAST FULL SCAN| IDX_T1_NAME | 49917 | 1218K| 57 (2)| 00:00:01 | 
————————————————————————————

這下終于走 Index 這條路老 : ) 在 Index 中, key value 是排序存放的. Index Fast full scan 它是按照 block 的存儲順序來讀取數據, 并可以一次 I / O 多塊讀取提高效率 (參數 readdb_file_multiblock_read_count), 但返回的值是沒有排序的. 而
Index full scan 會按照 Key value 順序讀取值, 返回排了序的結果. 所以, 做個 order by 會是走 Index full scan.

SQL select object_name from t1 order by object_name;

Execution Plan
———————————————————- 
Plan hash value: 1352742509

——————————————————————————– 
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | 
——————————————————————————– 
| 0 | SELECT STATEMENT | | 49917 | 1218K| 249 (1)| 00:00:03 | 
| 1 | INDEX FULL SCAN | IDX_T1_NAME | 49917 | 1218K| 249 (1)| 00:00:03 | 
——————————————————————————–

對于定義為 NULL 的列,創建位圖索引可走索引

上述就是丸趣 TV 小編為大家分享的如何進行 null 與 index 的分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-17發表,共計5248字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 吴川市| 天祝| 天等县| 香河县| 荔波县| 荣成市| 民县| 饶平县| 武穴市| 普兰店市| 无为县| 宜章县| 柳林县| 伊通| 石屏县| 余庆县| 淮安市| 湟源县| 舞钢市| 邻水| 九龙城区| 邵阳市| 松潘县| 大化| 和田县| 如东县| 蛟河市| 永安市| 廉江市| 左贡县| 佛教| 巨鹿县| 辽阳市| 海淀区| 古交市| 体育| 上思县| 张北县| 会同县| 宝鸡市| 绵竹市|