Oracle

是否值得在 Oracle 中按單個值對錶進行分區?

  • October 17, 2021

通常,如果您有一個經常查詢表的列,則應該在其上粘貼索引。但是,如果事先知道所有可能的值,是否還值得按此列對錶進行分區?假設您有一個表AUDIT,其中的TenantId列只能包含值:1, 2所有 SELECT語句都會有一個WHERE帶有TenantId參數的子句。

那麼,按 TenantId 對錶進行分區是否有益?如果是這樣,您還會在TenantId列上創建索引嗎?

partition by list (TENANTID)
(
 partition TENANT1 values (1),
 partition TENANT2 values (2)
)

我做了一個小實驗:插入隨機生成的TenantId的1M條記錄,從而創建:

  • 499652 條 TenantId=1 的記錄
  • 500348 條 TenantId=2 的記錄

以下是語句的查詢計劃:

SELECT * FROM table1 WHERE TENANTID=2

普通表(無索引,無分區) 普通表查詢計劃 點陣圖索引: 點陣圖索引查詢計劃 分區: 分區查詢計劃

順便說一句,如果我同時擁有索引和分區,查詢計劃使用分區而不是索引,因此該計劃看起來與上面顯示的第二個完全相同。

顯然分區獲勝,但它是嗎? 顯然,執行計劃中的成本列並不是判斷 SQL 語句響應時間的實際成本的可靠方法

那麼,最好的方法是什麼?如何選擇一個而不是另一個?

我的觀點是,以呈現的方式對該表進行分區可能是有用的。

如果進行全面掃描,您的查詢將快兩倍(在分區幾乎相等的情況下)。

如果您的查詢具有另一種過濾器/條件並使用索引,則分區沒有用,因為索引的級別幾乎不受值數量加倍的影響。

更新:對於您所做的測試(SELECT * FROM table1 WHERE TENANTID=2),可以肯定分區是最好的。點陣圖解決方案需要掃描索引,然後掃描所有包含行的表塊tenantid=2(它知道行是什麼)。但是分區將導致僅掃描 table 的帶有 tenantid=2 的分區。它們在物理上是分開的tenantid=1

因此,兩次掃描(索引掃描 + 表掃描)與一次表掃描(可能更小)。

當一列包含很少的不同值時,也就是低基數,就像你的情況一樣,你應該在它上面創建一個點陣圖索引。當您經常按該列查詢時,就是這樣。

以下是有關 Oracle 點陣圖索引的更多資訊: http ://www.dba-oracle.com/oracle_tips_bitmapped_indexes.htm

引用自:https://dba.stackexchange.com/questions/23720