我們在生產中有一個獨特的問題。在我們的批處理週期中,我們的Oracle 12c數據庫不時會在半夜中掛起。我們將不得不重新啓動數據庫以繼續進行幾天/每週。然後它再次發生。 一些挖後,我們已經把範圍縮小到這個SQL:Oracle中的神祕笛卡爾更新
UPDATE c_bill SET reason_desc = (SELECT description FROM codes
WHERE code_group = 'TRANSACTION_TYPE' AND code = c_bill.reason_code);
我已經改名爲表 - 但碼錶有代碼和說明。開發人員正在嘗試將描述從此複製到c_bill表。
此SQL是作爲批處理作業的一部分每晚運行的存儲過程的一部分。開發人員在此之前做了另一次更新,通過很好,但這個SQL需要很長時間。
在特定的運行過程中,該表有36308行。當我檢查生產DB(我看看V $ SQL表獲得的SQL),我看到以下內容:
Rows_processed爲第1更新36308 Rows_processed對於上述更新1318270864,那happpens是= 36308 * 36308! (笛卡爾積?)
我們在測試中沒有這個問題。當我嘗試UPDATE並解釋它在TEST中計劃時,沒有問題 - 它在UPDATE和v $ sql中都顯示了正確的36308行。
這是令人費解的。有沒有人在SQL中看到笛卡爾產品的機會?或者您是否瞭解Oracle 12c優化器中的任何錯誤,可能會將其變成笛卡爾產品(我們只是使用一些補丁修復了Group by by的錯誤)。
我有相當數量的Oracle經驗 - 我在這裏調查查詢。我建議開發人員添加一個where條件來確保。我們尚未對此進行測試。與此同時,我想通過甲骨文專家的採訪。任何意見/建議非常感謝。
更新:任何人都希望在這個崗位在將來 - 的問題不是笛卡爾乘積,但問題SQL更新在日同表的遊標循環中運行,因此看起來像笛卡爾。見Justin的答案。
'v $ sql'中的'executions' 1?或者是36308(即語句在每個36308次執行中更新了36308行)?你能得到該語句的查詢計劃(來自共享池還是來自AWR/Statspack)以查看它是否實際上具有笛卡爾積?'c_bill'是否有名爲'code_group'或'code'的列或只存在於'codes'中的列? –
我想你可能已經釘了它!執行= 36308並且是它所在的過程,它有一個光標,用於獲取c_bill表中的鍵的行。前面提到的更新實際上有遊標SQL中使用的鍵,但是這個沒有。我會做更多的測試並回傳。我不是DBA,我會在下週檢查AWR的統計數據(他們現在已經很長時間了!)。你可以請回復作爲答案? – SamV
再次從v $ sql中,問題UPDATE語句的last_load_time是last_load_time是2016-09-02/03:04:02 而last_active_time是09/02/2016 4:48。這是否意味着同一個SQL在那個小時內保持運行36308次? – SamV