優化一個sql時,想起了建立索引,不過不知道是應該分開建立(一個索引名對應一個欄位),還是應該一起建立(一個索引名對應多個欄位),這兩個在執行上有什么區別。
sql如下
SELECT "WW_BXB"."BXDBH",
"WW_BXB"."ZZBH",
"WW_BXB"."WXS",
"WW_BXB"."BXZZ",
"WW_BXB"."RID",
"WW_BXB"."GDXZ",
"CALL_DIRE_USER"."LEVEL1",
"WW_BXB"."ZONE",
"CALL_KH_LEVEL1"."KH_NAME",
"CALL_KH_LEVEL2"."KH_NAME",
"WW_BXB"."BGY",
"WW_BXB"."YD",
"WW_BXB"."WXLX",
"WW_BXB"."DHPZ_LX",
"WW_BXB"."DHPZ_ZT",
"WW_BXB"."DHPZ_SJ",
"WW_BXB"."DHPZ_CZZ",
"WW_BXB"."KSF_DH",
"KHXXDB"."KHMC",
"WW_BXB"."JZXH",
"WW_BXB"."PHONE",
"WW_BXB"."FAX",
"CALL_DIRE_USER"."MOBILE",
"WW_BXB"."KSF_ZCBH",
"WW_BXB"."PEPSI_DH",
"WW_BXB"."PEPSI_INTERID",
"WW_BXB"."PEPSI_ZCBH",
"CALL_DIRE_USER"."YYB",
"CALL_DIRE_USER"."YYS",
"CALL_DIRE_USER"."LINKMAN",
"CALL_DIRE_USER"."KH_SF",
"CALL_DIRE_USER"."KH_CITY",
"CALL_DIRE_USER"."KH_COUNTY",
"CALL_DIRE_USER"."KH_TOWN",
"CALL_DIRE_USER"."ADDRESS",
"WW_BXB"."TSWXLX",
"CALL_DIRE_USER"."LEVEL2",
"WW_BXB"."KSF_INTERID",
"WW_BXB"."TINGHSIN_SOUCE"
FROM "WW_BXB",
"WW_ZTB",
"CALL_DIRE_USER",
"CALL_KH_LEVEL1",
"CALL_KH_LEVEL2",
"KHXXDB"
WHERE ( call_dire_user.level1 = call_kh_level1.id_level1 (+)) and
( call_dire_user.level2 = call_kh_level2.id_level2 (+)) and
( ww_bxb.wxs = khxxdb.khbm (+)) and
( "WW_BXB"."ZJKHBM" = "CALL_DIRE_USER"."ID" ) and
( "WW_BXB"."BXDBH" = "WW_ZTB"."WXDBH" )
and ( ( "WW_ZTB"."PG" = '0' ) AND ( "WW_BXB"."BXR" not in ('頂津E站','百事E站','EXCEL') )
AND ("WW_BXB"."DHPZ_ZT" is null OR "WW_BXB"."DHPZ_ZT" <> '1')
AND ("WW_BXB"."GDXZ" is null OR "WW_BXB"."GDXZ" <> '08')
AND ("WW_BXB"."PDR" is null OR "WW_BXB"."PDR" like '%') );
疑惑點1.像 where后面的 ( call_dire_user.level1 = call_kh_level1.id_level1 (+)) and
( call_dire_user.level2 = call_kh_level2.id_level2 (+)) 這句話,我是把 call_dire_user這個表的level1和level2這兩個欄位分別建立兩個索引,還是把兩個欄位建立一個索引。
疑惑點2 像 ww_bxb這種表 每個and后都有一個欄位限定,我是把這幾個欄位捏在一起寫成一個索引,還是分別建立多個索引?
甚是迷惑
uj5u.com熱心網友回復:
1、你把索引建在驅動表的連接欄位上是沒用的,要建在被驅動表的連接欄位上,而且連接欄位可以建到一起;2、后面單表上的條件太復雜,而且還有is null這種,B樹索引如果未經任何加工,無論是單欄位還是多欄位索引處理這種條件都是力不從心的,在各個欄位上創建位圖索引是個選擇,但要求表上不能有并發DML。
uj5u.com熱心網友回復:
實際上我覺得你這樣的SQL,根本就不需要任何索引,因為這是個統計,每次參與連接的資料量完全不可控,還不如表掃描然后HASH JOIN搞定,這種SQL可以說不適合Oracle來處理,當然其他關系資料庫更不行,MPP或者hadoop才是解決之道。
uj5u.com熱心網友回復:
忍不住三連

既然是個統計,那么我就假設這是個倉庫類的資料庫了,那么一樓的優化可以考慮,因為至少這樣的索引可以優化一部分查詢(根據條件的不同,有一部分查詢可能涉及到的資料量較小)
uj5u.com熱心網友回復:
1、你把索引建在驅動表的連接欄位上是沒用的,要建在被驅動表的連接欄位上,而且連接欄位可以建到一起;
2、后面單表上的條件太復雜,而且還有is null這種,B樹索引如果未經任何加工,無論是單欄位還是多欄位索引處理這種條件都是力不從心的,在各個欄位上創建位圖索引是個選擇,但要求表上不能有并發DML。
實際上我覺得你這樣的SQL,根本就不需要任何索引,因為這是個統計,每次參與連接的資料量完全不可控,還不如表掃描然后HASH JOIN搞定,這種SQL可以說不適合Oracle來處理,當然其他關系資料庫更不行,MPP或者hadoop才是解決之道。
忍不住三連
既然是個統計,那么我就假設這是個倉庫類的資料庫了,那么一樓的優化可以考慮,因為至少這樣的索引可以優化一部分查詢(根據條件的不同,有一部分查詢可能涉及到的資料量較小)
首先,感謝大神的耐心解答
不過本人作為非專業資料人員有些地方不是特別能理解,驅動表就是指左鏈接的主表被,位圖索引從來沒用過,如果用的話,針對于這個sql應該怎么寫呢
uj5u.com熱心網友回復:
1、你把索引建在驅動表的連接欄位上是沒用的,要建在被驅動表的連接欄位上,而且連接欄位可以建到一起;
2、后面單表上的條件太復雜,而且還有is null這種,B樹索引如果未經任何加工,無論是單欄位還是多欄位索引處理這種條件都是力不從心的,在各個欄位上創建位圖索引是個選擇,但要求表上不能有并發DML。
實際上我覺得你這樣的SQL,根本就不需要任何索引,因為這是個統計,每次參與連接的資料量完全不可控,還不如表掃描然后HASH JOIN搞定,這種SQL可以說不適合Oracle來處理,當然其他關系資料庫更不行,MPP或者hadoop才是解決之道。
忍不住三連

既然是個統計,那么我就假設這是個倉庫類的資料庫了,那么一樓的優化可以考慮,因為至少這樣的索引可以優化一部分查詢(根據條件的不同,有一部分查詢可能涉及到的資料量較小)
1、你把索引建在驅動表的連接欄位上是沒用的,要建在被驅動表的連接欄位上,而且連接欄位可以建到一起;
2、后面單表上的條件太復雜,而且還有is null這種,B樹索引如果未經任何加工,無論是單欄位還是多欄位索引處理這種條件都是力不從心的,在各個欄位上創建位圖索引是個選擇,但要求表上不能有并發DML。
實際上我覺得你這樣的SQL,根本就不需要任何索引,因為這是個統計,每次參與連接的資料量完全不可控,還不如表掃描然后HASH JOIN搞定,這種SQL可以說不適合Oracle來處理,當然其他關系資料庫更不行,MPP或者hadoop才是解決之道。
忍不住三連
既然是個統計,那么我就假設這是個倉庫類的資料庫了,那么一樓的優化可以考慮,因為至少這樣的索引可以優化一部分查詢(根據條件的不同,有一部分查詢可能涉及到的資料量較小)
首先,感謝大神的耐心解答不過本人作為非專業資料人員有些地方不是特別能理解,驅動表就是指左鏈接的主表被,位圖索引從來沒用過,如果用的話,針對于這個sql應該怎么寫呢
對,驅動表就是主表,就是你這個外連接中記錄數更全的那張。
位圖索引創建語法與普通B樹索引差別就一點: create bitmap index .....
uj5u.com熱心網友回復:
忘了說,有一個關鍵的因素就是這個表肯定是有并發dml
如何優化很是頭疼啊
uj5u.com熱心網友回復:
忘了說,有一個關鍵的因素就是這個表肯定是有并發dml
如何優化很是頭疼啊
還有個辦法,為那幾個可能為null的欄位設定默認值,然后創建組合索引,不過,如果你的where條件組合多變的話,又要黃了
uj5u.com熱心網友回復:
根據上述的SQL來講,建立索引是對的,至于一個或多個要看你資料庫的能力了,還有最主要的是要優化sql。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/76501.html
標籤:基礎和管理
