DBLINK HINT /*+ driving_site(org) */ 最佳化策略和思路

hd_system發表於2016-11-18

使用DBLINK遠端訪問的最佳化策略和思路:

策略:遠端訪問,網路傳輸佔很大部分,最佳化原則,減少網路傳輸,將小的結果集拉到本地處理;

思路1:在遠端建立檢視;

思路2:使用DRIVING_SITE將資料拉到本地處理;

出現這種執行計劃,主要原因是使用了db link,要想看到執行計劃,可以加 hint,如: 
/*+remote_mapping(db_link)*/或/*+driving_site(table_name)*/

   用法:   /*+driving_site(table_name)*/  : table_name 一般是大表!


       在近期的一個資料庫查詢統計中,需要透過db_link跨庫進行表的關聯,其中A庫 中的某張擁有百萬以上資料的表與B庫 中的擁有千條記錄以上的表進行關聯。兩張表進行關聯的欄位都建有索引。但在實際查詢中如果從B庫進行兩表的關聯卻會導致A庫中大表的全表掃描,查詢速度慢是次要的,關鍵是全表掃描會影響到A庫的正常執行。

       透過對SQL語句的不斷調整、最佳化發現當兩表進行簡單的關聯查詢時,如果在select 後面採用"*"獲取所有資料時,查詢不會導致全表掃描,但在select 後面取具體欄位時將會導致大表的全表掃描。


在簡單查詢的基礎上進行group分組將直接導致大表的全表掃描,在此種情況下,所有的語句最佳化技巧都將失效,因為索引無效,此時必須採取特殊的方法建立起關聯查詢的索引,強制指定在關聯過程中那一張表作為主要驅動表,那一張作為從表。在跨庫關聯查詢的過程中,因為表不在同一個資料庫中(同時在不同的伺服器上)將導致關聯過程中將一張表的資料提取到另一個資料庫中進行關聯。此時問題出現,如果在關聯過程中將大表資料提取到小表所在庫進行運算將導致大表的全表掃描,整個運算過程將非常慢且影響A庫的正常執行。

      最終解決全表掃描的辦法是,如果在B庫對不同資料庫的兩張大小表進行關聯時,透過driving_site強制指定主驅動表,即以所指定的表為主要表,將其它表作為從表提取到驅動表所在的庫進行關聯運算。具體語句如下:

    select /*+driving_site(main)*/  a.*,b.* from A.a main@BigTableDB,B.b minor where main.id=minor.id and .......

這樣一來就可以避免大表所在庫的全表掃描,查詢速度將成級數級提高。

解釋:
當指定 /*+driving_site(main)*/ 時, 將會從minor表獲取全部資料到main表所在的資料庫來進行關聯運算.(索引起作用,速度快)
若指定 /*+driving_site(minor)*/ 時, oracle將會從main表獲取全部資料到minor表所在的資料庫來進行關聯運算.(索引失敗,全表掃描)

當然Oracle中有很多的關鍵字用於指定關聯查詢時的運算方法,等後面碰到具體應用例項實再作一一介紹。

引用:
DRIVING_SITE 作用和 ORDERED 類似。 DRIVING_SITE 通常在分散式查詢中使用。如果沒有這個提示, Oracle 會先從遠端點檢索,並將它們連線到本地站點中。透過使用 DRIVING_SITE ,我們可以先在本地進行檢索,將檢索後的資料傳送到遠端節點進行連線
********************************************************************************************************

出現這種執行計劃,主要原因是使用了db link,要想看到執行計劃,可以加 hint,如:
/*+remote_mapping(db_link)*/或/*+driving_site(table_name)*/


   用法:   /*+driving_site(table_name)*/  : table_name 一般是大表!

       在近期的一個資料庫查詢統計中,需要透過db_link跨庫進行表的關聯,其中A庫 中的某張擁有百萬以上資料的表與B庫 中的擁有千條記錄以上的表進行關聯。兩張表進行關聯的欄位都建有索引。但在實際查詢中如果從B庫進行兩表的關聯卻會導致A庫中大表的全表掃描,查詢速度慢是次要的,關鍵是全表掃描會影響到A庫的正常執行。

       透過對SQL語句的不斷調整、最佳化發現當兩表進行簡單的關聯查詢時,如果在select 後面採用"*"獲取所有資料時,查詢不會導致全表掃描,但在select 後面取具體欄位時將會導致大表的全表掃描。

      在簡單查詢的基礎上進行group分組將直接導致大表的全表掃描,在此種情況下,所有的語句最佳化技巧都將失效,因為索引無效,此時必須採取特殊的方法建立起關聯查詢的索引,強制指定在關聯過程中那一張表作為主要驅動表,那一張作為從表。在跨庫關聯查詢的過程中,因為表不在同一個資料庫中(同時在不同作業系統的伺服器上)將導致關聯過程中將一張表的資料提取到另一個資料庫中進行關聯。此時問題出現,如果在關聯過程中將大表資料提取到小表所在庫進行運算將導致大表的全表掃描,整個運算過程將非常慢且影響A庫的正常執行。

      最終解決全表掃描的辦法是,如果在B庫對不同資料庫的兩張大小表進行關聯時,透過driving_site強制指定主驅動表,即以所指定的表為主要表,將其它表作為從表提取到驅動表所在的庫進行關聯運算。具體語句如下:

    select /*+driving_site(main)*/  a.*,b.* from A.a minor where main.id=minor.id and .......

  這樣一來就可以避免大表所在庫的全表掃描,查詢速度將成級數級提高。

解釋:

當指定 /*+driving_site(main)*/ 時, oracle將會從minor表獲取全部資料到main表所在的資料庫來進行關聯運算.(索引起作用,速度快)
若指定 /*+driving_site(minor)*/ 時, oracle將會從main表獲取全部資料到minor表所在的資料庫來進行關聯運算.(索引失敗,全表掃描)

當然Oracle中有很多的關鍵字用於指定關聯查詢時的運算方法,等後面碰到具體應用例項實再作一一介紹。

引用:

DRIVING_SITE 作用和 ORDERED 類似。 DRIVING_SITE 通常在分散式查詢中使用。如果沒有這個提示, Oracle 會先從遠端點檢索,並將它們連線到本地站點中。透過使用 DRIVING_SITE ,我們可以先在本地進行檢索,將檢索後的資料傳送到遠端節點進行連線

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29209863/viewspace-2128684/,如需轉載,請註明出處,否則將追究法律責任。

相關文章