Oracle

創建索引語法無效

  • May 27, 2014

我無法使用該where子句創建索引。

請參閱以下查詢:

CREATE INDEX c_bplocation_isdefault 
ON c_bpartner_location 
 (ad_client_id,c_bpartner_id,isdefault) 
WHERE isdefault = 'Y';

Oracle 中的索引不能有WHERE子句。

您可以創建一個基於函式的索引(我isdefault從索引中刪除了第三列,因為我們知道這必須是Y這樣,所以它不會向索引添加任何選擇性)

CREATE INDEX c_bplocation_isdefault ON c_bpartner_location (
 case when isdefault = 'Y' then ad_client_id else null end,
 case when isdefault = 'Y' then c_bpartner_id else null end
) 

這利用了 Oracle 不會索引索引中所有列所在的條目的事實,NULL以減少索引的大小。但是,為了讓您的查詢使用索引,您需要使用與創建索引相同的表達式。就像是

SELECT *
 FROM c_bpartner_location 
WHERE (case when isdefault = 'Y' 
            then ad_client_id 
            else null 
        end) = <<some value>>
  AND (case when isdefault = 'Y' 
            then c_bpartner_id  
            else null 
        end) = <<another value>>
  AND isdefault = 'Y'

實際上,您通常最好創建一個在索引定義和查詢中都使用的實際函式,這樣您就不會CASE在多個位置對語句進行編碼。

恕我直言,下面將顯示一個更好的索引。您希望索引從一般開始然後變得具體。如果您可以為某些值創建索引,那麼為什麼需要索引中的該列,因為它已經是“Y”了。但是,如果您將其作為第一列,則所有帶有 isdefault=‘Y’ 的行都聚集在一起,因此您已經可以查看較小的索引部分來獲取所需的行。假設合作夥伴少於客戶,我將合作夥伴 ID 放在客戶 ID 之前。試試這個,看看它是否有效。

CREATE INDEX c_bplocation_isdefault 
   ON c_bpartner_location 
    ( isdefault, c_bpartner_id, ad_client_id );

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