好的,所以我正在研究這個(相當老的)項目,它使用了大量針對Oracle數據庫的查詢。我最近偶然發現了這個寶石,大約需要6-7小時小時才能運行並返回〜1400行。問題中的表格/視圖包含〜200'000行。我覺得這感覺好像比合理的時間稍長一點,所以我開始仔細觀察它。現在我不能,出於安全/特殊原因,共享準確的查詢,但這應該顯示查詢確實較一般什麼:驗證Oracle查詢的優化
SELECT
some_field,
some_other_field
FROM (
SELECT
*
FROM
some_view a
WHERE
some_criteria AND
a.client_no || ':' || a.engagement_no || ':' || a.registered_date = (
SELECT
b.client_no || ':' || b.engagement_no || ':' || MAX(b.registered_date)
FROM
some_view b
JOIN some_engagement_view e
ON e.client_no = b.client_no AND e.engagement_no = b.engagement_no
JOIN some_client_view c
ON c.client_no = b.client_no
WHERE
some_other_criteria AND
b.client_no = a.client_no AND
b.engagement_no = a.engagement_no
GROUP BY
b.client_no,
b.engagement_no
)
);
基本上什麼是應該做的,據我」我們設法弄清楚,是從some_view(其中包含對客戶/訂婚的評估)獲取每個獨特客戶/參與的最新評估。
這兩個連接可以確保客戶和參與在另一個系統中存在,在您完成系統評估後主要處理它們。
請注意它是如何連接兩個數字和日期,然後將其與子查詢進行比較? 「有趣」的設計選擇。所以我認爲如果用適當的比較來替換串聯,至少可以獲得某種性能增益。請注意,我主要開發.NET和網絡,以及當它涉及到數據庫的專家很遠,但我重寫,如下所示:
SELECT
some_field,
some_other_filed
FROM
some_view a
WHERE
some_criteria AND
(a.client_no, a.engagement_no, a.registered_date) = (
SELECT
b.client_no,
b.engagement_no,
MAX(b.registered_date)
FROM
some_view b
JOIN some_engagement_view e
ON e.client_no = b.client_no AND e.engagement_no = b.engagement_no
JOIN some_client_view c
ON c.client_no = b.client_no
WHERE
some_other_criteria AND
b.client_no = a.client_no AND
b.engagement_no = a.engagement_no
GROUP BY
b.client_no,
b.engagement_no
)
);
現在,如果我替換等領域都有了第一選擇與COUNT(1)
,我得到兩個查詢完全相同的行數,所以一個好的開始。新查詢提取數據的速度與其計數一樣快,< 10秒。舊的查詢在〜20秒內得到計數,正如我之前提到的那樣,數據需要接近6-7小時。它目前正在運行,因此我可以進行某種分析以查看新查詢是否有效,但是我認爲我也會在此問一下,看看我做了什麼明顯錯誤的事情?
編輯還刪除了最外面的查詢,這似乎並沒有履行任何樣的目的,除了可能使查詢外觀更酷..或東西..我不知道..
爲避免自己加入'some_view',可能值得考慮[分析函數](http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions004.htm)。但你應該看看解釋計劃,看看它花費的時間。 –