我正在嘗試編寫一個簡單的查詢來計算大表的結果。Where子句將查詢速度從2秒減慢到24秒
SELECT COUNT(*)
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3
WHERE (AL3.REFERENCE_YEAR(+) =2012)
上面的查詢需要大約24秒才能返回我的輸出。如果我刪除where子句並執行相同的查詢,它會在2秒內給出結果。
我想知道是什麼原因。我對SQL查詢比較陌生。
請幫
感謝, 納文
我正在嘗試編寫一個簡單的查詢來計算大表的結果。Where子句將查詢速度從2秒減慢到24秒
SELECT COUNT(*)
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3
WHERE (AL3.REFERENCE_YEAR(+) =2012)
上面的查詢需要大約24秒才能返回我的輸出。如果我刪除where子句並執行相同的查詢,它會在2秒內給出結果。
我想知道是什麼原因。我對SQL查詢比較陌生。
請幫
感謝, 納文
您可能需要在表上的索引。通常,你需要在where子句
爲我認爲這是多餘的(+)語法中使用任何列的索引(我不是甲骨文專家),但看到Difference between Oracle's plus (+) notation and ansi JOIN notation?
原因似乎微妙。但是Oracle可以通過多種方式來處理這樣的查詢:
SELECT COUNT(*)
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3
一種方法是讀取表中的所有行。因爲這是一張大桌子,這不是最有效的方法。第二種方法是使用某種類型的統計信息,其中行數在統計信息中。我不認爲Oracle會這樣做,但這是可以想象的。
最後的方法是讀取索引。通常,索引將比表和小得多,它可能已經在內存中。上述查詢將讀取的數據量小得多。 (Here是在一個表計算所有行的有趣的文章。)
當你介紹了where
條款,
WHERE (AL3.REFERENCE_YEAR(+) =2012)
Oracle可以不再僅僅掃描任何索引。它將不得不掃描reference_year
索引。問題是什麼?如果它掃描了一個索引,它仍然需要獲取數據記錄以得到reference_year
的值 - 這與掃描整個表相當(實際上更糟糕)。
即使在reference_year
上有索引,也不保證使用索引。問題是選擇性。相對於數據庫中的行數(在這種情況下,10%是「相當大」),您提取的行數可能仍然很大。 Oracle優化可以選擇執行全表掃描而不是讀取索引。
Oracle支持僅索引掃描,如果'reference_year'上有索引,它將不會從表中讀取任何內容。 (假設這是完整的查詢,並且沒有其他謂詞。) –
如何檢查該表和列是否存在索引? – user2503175
有很多免費工具可以查看數據庫的結構。您還可以從命令提示符管理它。 – KeepCalmAndCarryOn
或者您可以查看查詢計劃,例如EXPLAIN PLAN for SELECT last_name FROM employees; – KeepCalmAndCarryOn