2012-03-13 54 views
7

我有98w行數據。當我想用pub_time對數據進行排序時,我發現了一件有趣的事情。兩個sql用於排序時間戳日期

這裏是SQL:

select * 
from t_p_blog_article_info t 
order by t.pub_time desc 

它花費了19秒。

select * 
from t_p_blog_article_info t 
where t.pub_time > to_date('1900-01-01 01:00:00', 'yyyy-mm-dd hh24:mi:ss ') 
order by t.pub_time desc 

它花費0.2s。

我想知道,爲什麼?

+0

「pub_time」列是否有索引? – Ollie 2012-03-13 13:13:12

+0

只是一個猜測,但可以t.pub_time永遠是NULL? – markblandford 2012-03-13 13:13:36

+1

顯然你的where子句過濾了很多記錄,爲什麼? 'null'值,或者簡單地在01.01.1900之前輸入錯誤的時間值 – ntziolis 2012-03-13 13:16:57

回答

4

你可能在你的表上有一個關於pub_time的索引。

因此,第二個查詢可以使用此索引僅返回指定日期後具有非空日期的記錄,而第一個查詢必須查詢整個表。

+0

是的,我有pub_time的索引,但爲什麼第一個查詢不使用索引? – sarowlwp 2012-03-13 13:17:59

+0

雖然,正確地說,兩個查詢最終都不得不查詢整個表,因爲它們都有'SELECT *'和*大概*都返回所有行。 (至少,我懷疑OP會問這個問題,如果第二個查詢返回的行數更少。) – ruakh 2012-03-13 13:18:17

+0

@sarowlwp:索引不包含空值,因此如果'pub_time'可爲空(即使它實際上從不爲null),那麼對於其WHERE子句不排除記錄的查詢,其索引不足以滿足要求它是空的。 – ruakh 2012-03-13 13:19:54

0

有一系列的可能性。你可能會在pub_time中過濾掉大量帶有無效/空日期的行,但我懷疑你不會注意到/提及其中的大量行。

的三件事情,在我的腦海裏伸出有:

- 你有一個指數或涉及pub_time綜合指數,並限制你的where子句觸發使用不同的訪問路徑

- 運行第一個查詢時,您沒有可用於優化程序的統計信息。運行第二個查詢時,由於運行第一個查詢時發生的某些信息緩存,選擇了更好的訪問路徑。這可以通過多次運行第一個查詢並查看是否有顯着的性能改進來驗證。

- 與第一點類似,優化器可能僅僅根據where子句的含義選擇更好的訪問路徑。也許給暗示空值/無效值不需要處理就足夠了 - 您的系統可能會避免一個或多個全表掃描來清除無效/空pub_times。

查明這類事情的原因正在迅速成爲一種經驗性冒險 - 在不知道平臺版本的情況下,我很難說更多。從標籤中我可以看出你使用的是oracle,在這種情況下,你應該能夠使用某種形式的「解釋查詢」或「解釋計劃」工具來更好地理解發生了什麼。有關oracle優化器的更多信息,請參閱http://docs.oracle.com/cd/B10500_01/server.920/a96533/optimops.htm(這是針對Oracle 9i v9.2的,但它對版本無關概念有一個體面的解釋)