CLUSTERING_FACTOR、回表、資料分佈傾斜走全表還是索引
CLUSTERING_FACTOR Indicates the amount of order of the rows in the table based on the values of the index.
■ If the value is near the number of blocks, then the
table is very well ordered. In this case, the index
entries in a single leaf block tend to point to rows in
the same data blocks.
■ If the value is near the number of rows, then the
table is very randomly ordered. In this case, it is
unlikely that index entries in the same leaf block
point to rows in the same data blocks.
Assessing I/O for Blocks, not Rows
Oracle Database performs I/O by blocks. Therefore, the optimizer's decision to use full table scans is influenced by the percentage of blocks accessed, not rows. This is called the index clustering factor. If blocks contain single rows, then rows accessed and blocks accessed are the same.
However, most tables have multiple rows in each block. Consequently, the desired number of rows may be clustered in a few blocks or spread out over a larger number of blocks.
Although the clustering factor is a property of the index, the clustering factor actually relates to the spread of similar indexed column values within data blocks in the table. A lower clustering factor indicates that the individual rows are concentrated within fewer blocks in the table. Conversely, a high clustering factor indicates that the individual rows are scattered more randomly across blocks in the table. Therefore, a high clustering factor means that it costs more to use a range scan to fetch rows by rowid, because more blocks in the table need to be visited to return the data
索引掃描取OR全表掃描決於:
1、
2、where條件囊括的資料塊佔整表資料塊範圍比較小,為什麼是資料塊,而非資料行數?主要是因為有一個索引聚類因子的概念
Oracle資料庫透過塊執行I/O。 因此,最佳化器使用全表掃描的決定受到訪問塊的百分比而不是行的影響。 這稱為索引聚類因子。 如果塊包含單行,則訪問的行和訪問的塊是相同的。
但是,大多數表在每個塊中都有多行。 因此,期望數量的行可以聚集在幾個塊中或者擴充套件到更大的數目的塊。
雖然聚類因子是索引的屬性,但聚類因子實際上與表中資料塊內類似索引列值的擴充套件有關。 較低的聚類因子表示各行集中在表中較少的塊中。 相反,高聚類因子表明單獨的行在表中的塊之間更隨機地散佈。 因此,高聚類因素意味著使用範圍掃描以rowid獲取行花費更多,因為表中的更多塊需要被訪問才能返回資料
檢視ALL_INDEXES的CLUSTERING_FACTOR*值來判斷資料的離散程度
假如表的總塊數是5000個塊,有1000000行,如果表的資料太離散,帶上where 條件object_id=100的資料只有10000行(1%的資料),但是分佈在太多不同的塊上假如就是5000個塊,走索引10000次就需要訪問5000個資料塊,成本IO等於5000資料塊+索引塊數>整表塊數,那肯定走全表掃描了。
如果表的資料不那麼離散,object_id=100的資料分佈就在200個塊上,成本IO等於200資料塊+索引塊數<整表塊數,那肯定走索引掃描了。
如下三種資料傾斜情況
SQL> select * from test where object_id=1;--資料佔95%,理應走全表
SQL> select * from test where object_id=2;--資料佔1%,理應走索引
SQL> select * from test where object_id=3;--資料佔1%,理應走索引
如果CLUSTERING_FACTOR值是建議走索引。
比如第一個語句,它也不會走全表而是直接走了索引
比如表的總塊數是100個塊(可能有空塊或半空塊),object_id=1卻只佔據了50個塊,select全表掃描時會掃描HWM以內的所有塊,即100個塊
但是索引掃描時,只是去定位到那50個塊,成本為索引塊+50資料塊<全表的100資料塊
如果CLUSTERING_FACTOR值是建議走全表。
上面第二、三個語句,它也不會走索引而是直接走了全表
一個索引塊中索引值如下
A
A
A
B
B
B
C
C
C
三個資料塊中資料分佈如下1
A
B
C
A
B
C
A
B
C
三個資料塊中資料分佈如下2
A
A
A
B
B
B
C
C
C
按分佈1的情況,找到對應行,需要9次IO
A要訪問3個資料塊
B要訪問3個資料塊
C要訪問3個資料塊
總計需要訪問9次資料塊
按分佈2的情況,找到對應行,需要3次IO
A要訪問1個資料塊
B要訪問1個資料塊
C要訪問1個資料塊
總計需要訪問3次資料塊
回表開銷:索引儲存索引列的值和rowid,可以透過rowid定位回到表中,得到這個索引列以外的列資訊,要做這個類事,必然有開銷
其實回表,不就是去訪問表中某些具體的行嘛,如果回表涉及的行的資料塊數量佔整表所有行資料塊數量的80%,那不就是回表成本太高嗎,所以回表和資料離散程度相關
按上面的例子,回表要回10000次,比全表掃描1000000行開銷總要少吧
比如不走索引,直接select * from table,總計1000000,難道不就是回表1000000次嗎
針對查詢較少列的sql,還可以透過建立複合索引,使sql一次將資料從索引段中讀取出來,不用回表。
select id,name from tab_t where id=1;而(id,name)是複合索引,這種情況下就不用回表。
■ If the value is near the number of blocks, then the
table is very well ordered. In this case, the index
entries in a single leaf block tend to point to rows in
the same data blocks.
■ If the value is near the number of rows, then the
table is very randomly ordered. In this case, it is
unlikely that index entries in the same leaf block
point to rows in the same data blocks.
Assessing I/O for Blocks, not Rows
Oracle Database performs I/O by blocks. Therefore, the optimizer's decision to use full table scans is influenced by the percentage of blocks accessed, not rows. This is called the index clustering factor. If blocks contain single rows, then rows accessed and blocks accessed are the same.
However, most tables have multiple rows in each block. Consequently, the desired number of rows may be clustered in a few blocks or spread out over a larger number of blocks.
Although the clustering factor is a property of the index, the clustering factor actually relates to the spread of similar indexed column values within data blocks in the table. A lower clustering factor indicates that the individual rows are concentrated within fewer blocks in the table. Conversely, a high clustering factor indicates that the individual rows are scattered more randomly across blocks in the table. Therefore, a high clustering factor means that it costs more to use a range scan to fetch rows by rowid, because more blocks in the table need to be visited to return the data
索引掃描取OR全表掃描決於:
1、
where條件囊括的資料鍵值在索引上能夠找到,詳見NULL相關知識點
2、where條件囊括的資料塊佔整表資料塊範圍比較小,為什麼是資料塊,而非資料行數?主要是因為有一個索引聚類因子的概念
Oracle資料庫透過塊執行I/O。 因此,最佳化器使用全表掃描的決定受到訪問塊的百分比而不是行的影響。 這稱為索引聚類因子。 如果塊包含單行,則訪問的行和訪問的塊是相同的。
但是,大多數表在每個塊中都有多行。 因此,期望數量的行可以聚集在幾個塊中或者擴充套件到更大的數目的塊。
雖然聚類因子是索引的屬性,但聚類因子實際上與表中資料塊內類似索引列值的擴充套件有關。 較低的聚類因子表示各行集中在表中較少的塊中。 相反,高聚類因子表明單獨的行在表中的塊之間更隨機地散佈。 因此,高聚類因素意味著使用範圍掃描以rowid獲取行花費更多,因為表中的更多塊需要被訪問才能返回資料
檢視ALL_INDEXES的CLUSTERING_FACTOR*值來判斷資料的離散程度
假如表的總塊數是5000個塊,有1000000行,如果表的資料太離散,帶上where 條件object_id=100的資料只有10000行(1%的資料),但是分佈在太多不同的塊上假如就是5000個塊,走索引10000次就需要訪問5000個資料塊,成本IO等於5000資料塊+索引塊數>整表塊數,那肯定走全表掃描了。
如果表的資料不那麼離散,object_id=100的資料分佈就在200個塊上,成本IO等於200資料塊+索引塊數<整表塊數,那肯定走索引掃描了。
如下三種資料傾斜情況
SQL> select * from test where object_id=1;--資料佔95%,理應走全表
SQL> select * from test where object_id=2;--資料佔1%,理應走索引
SQL> select * from test where object_id=3;--資料佔1%,理應走索引
如果CLUSTERING_FACTOR值是建議走索引。
比如第一個語句,它也不會走全表而是直接走了索引
比如表的總塊數是100個塊(可能有空塊或半空塊),object_id=1卻只佔據了50個塊,select全表掃描時會掃描HWM以內的所有塊,即100個塊
但是索引掃描時,只是去定位到那50個塊,成本為索引塊+50資料塊<全表的100資料塊
如果CLUSTERING_FACTOR值是建議走全表。
上面第二、三個語句,它也不會走索引而是直接走了全表
一個索引塊中索引值如下
A
A
A
B
B
B
C
C
C
三個資料塊中資料分佈如下1
A
B
C
A
B
C
A
B
C
三個資料塊中資料分佈如下2
A
A
A
B
B
B
C
C
C
按分佈1的情況,找到對應行,需要9次IO
A要訪問3個資料塊
B要訪問3個資料塊
C要訪問3個資料塊
總計需要訪問9次資料塊
按分佈2的情況,找到對應行,需要3次IO
A要訪問1個資料塊
B要訪問1個資料塊
C要訪問1個資料塊
總計需要訪問3次資料塊
回表開銷:索引儲存索引列的值和rowid,可以透過rowid定位回到表中,得到這個索引列以外的列資訊,要做這個類事,必然有開銷
其實回表,不就是去訪問表中某些具體的行嘛,如果回表涉及的行的資料塊數量佔整表所有行資料塊數量的80%,那不就是回表成本太高嗎,所以回表和資料離散程度相關
按上面的例子,回表要回10000次,比全表掃描1000000行開銷總要少吧
比如不走索引,直接select * from table,總計1000000,難道不就是回表1000000次嗎
針對查詢較少列的sql,還可以透過建立複合索引,使sql一次將資料從索引段中讀取出來,不用回表。
select id,name from tab_t where id=1;而(id,name)是複合索引,這種情況下就不用回表。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2143207/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一種自平衡解決資料傾斜的分表方法
- Hive資料傾斜Hive
- Oracle中利用函式索引處理資料傾斜案例Oracle函式索引
- 巧用函式索引解決資料傾斜列查詢函式索引
- Spark學習——資料傾斜Spark
- 資料傾斜解決辦法
- IoT資料傾斜如何解決
- 有索引卻走全表掃描的實驗分析索引
- (轉)索引掃描還是全表掃描(Index Scan Or Full Table Scan)索引Index
- 轉)索引掃描還是全表掃描(Index Scan Or Full Table Scan)索引Index
- Hash分割槽表及資料分佈
- 編號函式 自定義函式 集合型別 表的優化 資料傾斜函式型別優化
- Spark 資料傾斜及其解決方案Spark
- hive優化-資料傾斜優化Hive優化
- 資料庫表,索引(索引組織表,聚簇表,聚簇索引,)資料庫索引
- 資料庫系列:覆蓋索引和規避回表資料庫索引
- 大資料常見問題之資料傾斜大資料
- Hive千億級資料傾斜解決方案Hive
- 【Hive】資料傾斜優化 shuffle, join, group byHive優化
- Redis 切片叢集的資料傾斜分析Redis
- 還傻傻分不清MySQL回表查詢與索引覆蓋?MySql索引
- hadoop 透過cachefile來避免資料傾斜Hadoop
- PostgreSQL DBA(193) - 資料傾斜下的HashJoinSQL
- 【Spark篇】---Spark解決資料傾斜問題Spark
- 索引掃描可能不如全表掃描的場景的理解__純粹資料量而言,不涉及CLUSTERING_FACTOR索引
- delete 刪除資料 全表掃描還是掃描所有塊的測試delete
- oracle分表效率,資料庫分庫分表是什麼,什麼情況下需要用分庫分表Oracle資料庫
- 大資料SQL優化之資料傾斜解決案例全集大資料SQL優化
- 分庫分表插入資料
- 資料庫分庫分表資料庫
- MySQL 的覆蓋索引與回表MySql索引
- MySQL 覆蓋索引、回表查詢MySql索引
- 【Oracle】-【索引】先查資料再建索引,還是先建索引再插資料?Oracle索引
- 千萬級資料庫使用索引查詢速度更慢的疑惑-資料回表問題資料庫索引
- Spark效能最佳化篇三:資料傾斜調優Spark
- 如何解決 Redis 資料傾斜、熱點等問題Redis
- 淺析 Hadoop 中的資料傾斜(R0.1)Hadoop
- SAP中的資料庫表索引資料庫索引