2012-11-15 111 views
2

我正在使用現有的Oracle數據庫(我沒有構建,並且對其表結構超出瞭解一無所知)。有些查詢速度很快,其他看起來非常相似的查詢速度非常慢。例如瞭解SQL查詢時間

SELECT a.price, c.banner_id, c.short_name 
FROM ret_price_current a 
    JOIN ret_store b ON a.store_id = b.store_id 
    JOIN ret_banner c ON b.banner_id = c.banner_id 
    JOIN ret_store2cbsa_csa d ON a.store_id = d.store_id 
WHERE rownum<3 

(1.09, 74, 'Safeway') 
(1.09, 74, 'Safeway') 
that took 0.243073940277 seconds 

,但如果我添加了一個看似簡單的WHERE條件:

SELECT a.price, c.banner_id, c.short_name 
FROM ret_price_current a 
    JOIN ret_store b ON a.store_id = b.store_id 
    JOIN ret_banner c ON b.banner_id = c.banner_id 
    JOIN ret_store2cbsa_csa d ON a.store_id = d.store_id 
WHERE c.banner_id = 74 
    AND rownum<3 

已經運行沒有回來,現在許多分鐘。到底是怎麼回事? (作爲參考,ret_price_current有300m條目,其他條目要小得多。)我想它與索引有關 - 有人可以指點我一本關於數據庫算法的書(比如查詢實際上在後端如何工作),所以我可以理解wtf正在進行?

+1

您可能需要banner_id上的索引或banner_id和rownum上的索引。 rownum場有什麼桌子? –

+2

rownum只是告訴oracle只返回前n行 – andyInCambridge

+0

我看不到任何c.banner_id = 74會比第三次連接慢的原因。 b.banner_id = 74會發生什麼? –

回答

2

原因是ROWNUM是在輸出行時生成的。

您的第一個查詢沒有critera,因此它會吐出前3行並完成它。通常可以找到任何匹配相當快的3行。

你的第二個人必須找到3條符合標準的行,然後才能停止(並且它可能永遠找不到那3行)。

查詢是完全不同的,因此執行的時間不同。

讓這個運行速度快的方法是索引c.banner_id(實際上是所有的FK)。

oops - 剛注意到另一個答案的時間戳。無論如何,我會在這裏留下它,因爲它回答了問題,其中一條評論也如此。

+0

+1不要擔心提問時間戳。最近,各種各樣的問題都通過編輯而復活。 –