2012-09-05 46 views
0

我在oracle中有以下delete查詢。每次將有大約1000條記錄從數據庫中刪除。如何優化以下刪除SQL查詢?

我已經使用「在」查詢。有沒有更好的方法來編寫這個查詢?

DELETE FROM BI_EMPLOYEE_ACTIVITY  
WHERE EMPLOYEE_ID in ( 
    SELECT  
     EMP_ID 
    FROM 
     BI_EMPLOYEE 
    WHERE 
     PRODUCT_ID = IN_PRODUCT_ID 
); 
+2

把索引放在EMP_ID上可能會有所幫助,我不相信如果有其他優化是可能的,查詢是非常簡單和直接的 –

+1

爲什麼你需要優化?你是否面臨性能問題?在1000條記錄中,你實際上不應該面臨任何問題。除了查詢看起來很好。 – CloudyMarble

+1

@ O.D OP正在刪除1000條記錄,但我們不知道他從多少條記錄中選擇了那百條記錄。如果有10個Mil +記錄要搜索,則可能存在性能問題。 – danish

回答

0

這是不是真的能夠回答這個問題,因爲我們錯過了數據分佈的描述上BI_EMPLOYEE_ACTIVITY表的索引:有多少行是每個表?表格之間有什麼關係?有多少行受到刪除的影響?

我會假設這兩個表都很大(因爲這是一個優化問題)並且BI_EMPLOYEEBI_EMPLOYEE_ACTIVITY有親子1..N關係。

如果受刪除影響的行數很少,這意味着沒有多少員工具有相同的PRODUCT_ID,並且每個員工的活動很少。在這種情況下,索引BI_EMPLOYEE (product_id)BI_EMPLOYEE_ACTIVITY (employee_id)是有意義的。

儘管這可能並非如此,但刪除可能會影響很多行。在這種情況下,指數可能是一個障礙。如果刪除影響很多行,最快的訪問路徑可能是FULL TABLE SCAN + HASH JOIN

我們在這裏需要一些指標:有多少行被刪除?多久時間?這是因爲大DML總是需要時間,尤其是DELETE,因爲它們會產生最大量的撤消。

還有其他選擇大DELETE,從asktom在"Deleting many rows from a big table"解釋說:

  1. 重新創建表,而不刪除的行
  2. 分區中的數據,執行並行刪除
  3. 分區中的數據,從而刪除是通過刪除分區來完成的
+0

嗨桌子不會那麼大。 BI_EMPLOYEE最多可能有2萬個左右。未來它可能會在很大程度上增加。一個員工可以有多個活動,所以是的,這個表格將是巨大的。 – ashishjmeshram

+0

其他問題呢?更新會影響多少行?多久時間?你的目標是什麼? –

0

上EMP_ID把指數可能會有幫助,我不相信,如果任何其他的優化是可能的,查詢是非常簡單和直接的

0

創建於PRODUCT_ID列的索引。這會加快搜索速度。如果列是VARCHAR類型的,使用的功能指標,如果要轉換價值爲大寫或小寫

0

也許你可以試試EXIST代替的:

DELETE FROM BI_EMPLOYEE_ACTIVITY  
WHERE EXISTS ( 
    SELECT  
     EMP_ID 
    FROM 
     BI_EMPLOYEE 
    WHERE 
     PRODUCT_ID = IN_PRODUCT_ID 
    AND 
     EMP_ID = EMPLOYEE_ID 
); 
0

BI_EMPLOYEEPRODUCT_ID, EMP_ID創建索引按順序排列(product_id放在第一位)。

,併爲列EMPLOYEE_ID

0

我只是補充說,除了爲查詢創建索引之外,您需要查看錶的增長真的很大時的鎖定問題,嘗試以獨佔模式鎖定表(如果可能的話),因爲這隻會從數據庫獲取鎖定,並且如果無法嘗試提交每2500條記錄的刪除所以如果你堅持行鎖定,你最終不會餓死鎖的數據庫。