2013-06-20 56 views
0

我正在嘗試編寫一個簡單的查詢來計算大表的結果。Where子句將查詢速度從2秒減慢到24秒

SELECT COUNT(*) 
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3 
WHERE (AL3.REFERENCE_YEAR(+) =2012) 

上面的查詢需要大約24秒才能返回我的輸出。如果我刪除where子句並執行相同的查詢,它會在2秒內給出結果。

我想知道是什麼原因。我對SQL查詢比較陌生。

請幫

感謝, 納文

回答

1

您可能需要在表上的索引。通常,你需要在where子句

爲我認爲這是多餘的(+)語法中使用任何列的索引(我不是甲骨文專家),但看到Difference between Oracle's plus (+) notation and ansi JOIN notation?

+0

如何檢查該表和列是否存在索引? – user2503175

+0

有很多免費工具可以查看數據庫的結構。您還可以從命令提示符管理它。 – KeepCalmAndCarryOn

+0

或者您可以查看查詢計劃,例如EXPLAIN PLAN for SELECT last_name FROM employees; – KeepCalmAndCarryOn

0

原因似乎微妙。但是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優化可以選擇執行全表掃描而不是讀取索引。

+0

Oracle支持僅索引掃描,如果'reference_year'上有索引,它將不會從表中讀取任何內容。 (假設這是完整的查詢,並且沒有其他謂詞。) –