2017-10-17 124 views
0

我在Oracle 11g和我們有這3個核心表:優化與Oracle數據庫的幫助搜索

Customer - CUSTOMERID|DOB 
CustomerName - CUSTOMERNAMEID|CustomerID|FNAME|LNAME 
Address - ADDRESSID|CUSTOMERID|STREET|CITY|STATE|POSTALCODE 

我對每個表的數據和大約60萬行是美國和加拿大的混合人口。

我有一個調用Web服務的前端應用程序,他們做姓氏和部分zip搜索。所以我的查詢基本上有

where CUSTOMERNAME.LNAME = ? and ADDRESS.POSTALCODE LIKE '?%' 

它們通常提供zip的前3位數字。

地址表在所有街道/城市/州/郵政編碼和另一個州和郵政編碼索引。

我曾嘗試添加專用於zip的索引,並強制oracle在我的查詢中使用該索引,但這沒有任何區別。

對於返回約100行(我有分頁,一次只返回100)大約需要30秒,這是不理想的。我能做些什麼來改善這一點?

+0

您需要顯示您的查詢。我的猜測是這些表在CUSTOMERID上連接,所以CUSTOMERID s/b在每個表上編入索引。 –

+0

問題是郵政編碼是全部數字(如果你正在談論美國),但它們存儲爲字符串(實際上沒有太多的選擇)。即使使用索引,沒有更多的幫助,Oracle不知道在099和100之間它不需要查找09A和09W。所以它的基數估計將會消失。一種幫助Oracle的方法是添加直方圖。 https://docs.oracle.com/database/121/TGSQL/tgsql_histo.htm#TGSQL366 – mathguy

+0

然後:LNAME應該比POSTALCODE更有選擇性,但是您沒有提到LNAME上的索引。有一個嗎? – mathguy

回答

0

問題是您正在應用的過濾器不是非常有選擇性的,它們適用於不同的表格。這對於老式的btree索引是不利的。如果內容非常靜態,您可以嘗試使用位圖索引。更確切地說,在姓氏的前三個字母上的基於功能的位圖連接索引和在郵政編碼列上的位圖連接索引。這個假設很少有姓氏以某些字母開頭的人住在某個特定的郵政編碼中。

CREATE BITMAP INDEX ix_customer_custname ON customer(SUBSTR(cn.lname,1,3)) 
FROM customer c, customername cn 
WHERE c.customerid = cn.customerid; 

CREATE BITMAP INDEX ix_customer_postalcode ON customer(SUBSTR(a.postalcode,1,3)) 
FROM customer c, address a 
WHERE c.customerid = a.customerid; 

如果你成功了,你應該看到兩個位圖索引變成AND連接。執行時間應該下降到幾秒鐘。它不會像btree指數那麼快。

備註:

  • 你可能要繞一點發揮它是否是更有效地使一個或兩個指標,是否功能是有益有用的。

  • 如果你決定這樣做,你應該在查詢的where子句中包含完全相同的函數調用。否則,索引將不會被使用。

  • DML操作將會相當慢。這僅對具有靜態數據的表有用。請注意,DML操作會阻止整行「範圍」。併發DML操作會遇到問題。

  • 響應時間可能仍然是秒不像BTREE索引那樣瞬間。

  • AFAIK這隻適用於企業版。該語法未經測試,因爲我目前沒有可用的企業數據庫。

  • 如果仍然不夠快,您可以使用customerid,姓氏和郵政編碼創建物化視圖,但可以使用btree索引。但是這樣也很昂貴。

+3

如果有任何級別的併發寫入表,我會建議不要使用'BITMAP'索引。 –

+0

我同意100%。一旦你的表上有位圖索引,你就再也沒有行鎖。在該平臺上運行並行DML操作正在尋求麻煩。 – fhossfel

+0

謝謝。是的,會有同時寫作。但是BITMAP索引聽起來對於我們的另一個用例來說是個好主意。 – user3726933