2014-02-21 113 views
0

客戶表包含950萬條記錄。 customer_id列是主鍵。數據庫是oracle。oracle複合索引列位置和非複合索引

問題:

  1. 爲了提高性能,應該組合鍵包含customer_id欄也?
    例如:組合鍵包含(列位置1中的occupation_type和列位置2中的customer_id)。這有用嗎? customer_id已被索引爲主鍵的一部分。

  2. 在什麼列位置customer_id被包括在內,首先還是最後,這樣做的基礎是什麼?假設組合鍵包含3列,那麼customer_id列應該在哪個位置?

  3. 如果查詢包含where子句只適用於組合索引列位置3中的列,會發生什麼情況?是複合指數有用嗎?

  4. 如果場景要運行諸如(無特定順序)的查詢,是否應該獨立或以複合方式構建索引。在下面的情況下哪些有用?

查詢1:where tableA.columnA = value
QUERY2:where tableA.columnB = value
QUERY3:where tableA.columnC = value

回答

2

這是我爲你的情況做的數據設置。

CREATE TABLE TESTING 
(
    COLUMN1 NUMBER (10) PRIMARY KEY, 
    COLUMN2 CHAR (12), 
    COLUMN3 VARCHAR2 (12), 
    COLUMN4 VARCHAR2 (12), 
    COLUMN5 VARCHAR2 (12) 
); 

INSERT INTO TESTING 
    (SELECT ROWNUM, 
      DBMS_RANDOM.STRING ('U', 5), 
      DBMS_RANDOM.STRING ('U', 10), 
      DBMS_RANDOM.STRING ('L', 10), 
      DBMS_RANDOM.STRING ('L', 10) 
    FROM ALL_OBJECTS 
    WHERE ROWNUM <= 50000); 

Q1:A1完全取決於你想要什麼。既然你提到過。 "To improve performance",我們不能提供任何意見。但一般來說,對於複合索引而言,它總是被存儲,按鍵順序排序。當你選擇一些屬於任何索引(NOT NULL)的東西時,那麼在這種情況下,使用FAST FULL SCAN

SET AUTOTRACE ON 

SELECT COUNT(DISTINCT COLUMN1) FROM TESTING; 

EXECUTION PLAN 
---------------------------------------------------------- 
    0  SELECT STATEMENT OPTIMIZER MODE=ALL_ROWS (COST=29 CARD=1 BYTES=13) 
    1 0 SORT AGGREGATE (CARD=1 BYTES=13) 
    2 1  VIEW SYS.VW_DAG_0 (COST=29 CARD=40 K BYTES=517 K) 
    3 2  HASH GROUP BY (COST=29 CARD=40 K BYTES=517 K) 
    4 3   INDEX FAST FULL SCAN SYS_C0016669 (COST=27 CARD=40 K BYTES=517 K) 

萬一where子句包含索引列,則索引範圍掃描發生

SET AUTOTRACE ON 

SELECT COUNT(DISTINCT COLUMN1) FROM TESTING WHERE COLUMN1 < 10; 

EXECUTION PLAN 
---------------------------------------------------------- 
    0  SELECT STATEMENT OPTIMIZER MODE=ALL_ROWS (COST=2 CARD=1 BYTES=13) 
    1 0 SORT AGGREGATE (CARD=1 BYTES=13) 
    2 1  VIEW SYS.VW_DAG_0 (COST=2 CARD=5 BYTES=65) 
    3 2  SORT GROUP BY NOSORT (COST=2 CARD=5 BYTES=65) 
    4 3   INDEX RANGE SCAN SYS_C0016669 (COST=2 CARD=5 BYTES=65) 

讓我創建一個綜合指數

CREATE INDEX IDX_TEST_1 ON TESTING(COLUMN2, COLUMN3); 
CREATE INDEX IDX_TEST_2 ON TESTING(COLUMN1, COLUMN2); 

這有沒有影響,除非您使用他們在你的謂詞中。 A2:所以指數

SET AUTOTRACE ON 

SELECT COUNT(DISTINCT COLUMN1) FROM TESTING WHERE COLUMN1 < 10; 


EXECUTION PLAN 
---------------------------------------------------------- 
    0  SELECT STATEMENT OPTIMIZER MODE=ALL_ROWS (COST=2 CARD=1 BYTES=13) 
    1 0 SORT AGGREGATE (CARD=1 BYTES=13) 
    2 1  VIEW SYS.VW_DAG_0 (COST=2 CARD=5 BYTES=65) 
    3 2  SORT GROUP BY NOSORT (COST=2 CARD=5 BYTES=65) 
    4 3   INDEX RANGE SCAN SYS_C0016669 (COST=2 CARD=5 BYTES=65) 

Q2後,上述聲明將不會改變計劃。如果CUSTOMER_ID將在where子句中與另一列頻繁使用,那麼在這種情況下,請使用組合索引。第一列應該是排序的那一列。所以在你的情況下,它應該是索引

(x,y)上的索引將具有低聚類因子。 (由於該數據由x排序)上(Y,X)將具有高的聚類因子(由於數據不是由y排序)

AskTom said once

一種INDEX_FFS(索引快速全索引掃描)是一個通過讀取索引數據就好像它是表的過程。通常,索引一次處理一個塊。轉到根塊,使用分支塊進行導航。這是一個數據結構。

在FAST FULL SCAN中,我們只是讀取了磁盤上存在的整個結構。我們不把它當作索引,而更像是一張表。我們按順序讀取它(數據不會從索引ffs中進行排序),並使用多塊IO讀取它。

這使我們可以使用索引,如表格的「skinnier」版本。

我們可以:

範圍掃描和索引(升序或降序) 組合索引(我們做的位圖索引如何處理複雜和/或條件)連接索引(使用兩個或多個索引加盟一起) 全掃描索引如上。

您應該始終索引表格以檢索數據。

Q3:A3

SET AUTOTRACE ON 
SELECT COUNT(DISTINCT COLUMN1) FROM TESTING WHERE COLUMN3 = 'ASASDFF'; 

EXECUTION PLAN 
---------------------------------------------------------- 
    0  SELECT STATEMENT OPTIMIZER MODE=ALL_ROWS (COST=138 CARD=1 BYTES=13) 
    1 0 SORT AGGREGATE (CARD=1 BYTES=13) 
    2 1  VIEW SYS.VW_DAG_0 (COST=138 CARD=5 BYTES=65) 
    3 2  HASH GROUP BY (COST=138 CARD=5 BYTES=105) 
    4 3   TABLE ACCESS FULL TESTING (COST=137 CARD=5 BYTES=105) 

這裏儘管我們有包括欄3一個綜合指數,它是無用的

因此,對於Q4:A4,它始終是最好有個別比具有複合材料的要多

0
  1. 與不同價值觀的最高數欄應該先走了。也就是說,如果OCCUPATION_TYPE具有比CUSTOMER_ID更少不同值,且打算將查詢

    WHERE CUSTOMER_ID = X AND OCCUPATION_TYPE = Y 
    

    然後創建CUSTOMER_ID第一和第二OCCUPATION_TYPE複合索引。

  2. 見上。它可能應該是第一個,如果它將被包含在查詢中。

  3. 它可能是,但優化器將不得不評估是否執行索引跳過掃描,然後檢索實際數據比全表掃描更快。

  4. 根據你的示例查詢,我不明白你爲什麼會在幾個單列索引中使用組合。

編輯:固定編號。