2013-09-16 37 views
2

我有3代表與主要字符串數據和唯一id列:在多個表中的行計數導致大的延遲

categories ~45 rows 
clientfuncs ~800 rows 
serverfuncs ~600 rows 

所有表具有唯一的主AI欄的「id」。 我嘗試在一個查詢數行:

SELECT COUNT(categories.id), COUNT(serverfuncs.id), COUNT(clientfuncs.id) FROM categories, serverfuncs, clientfuncs 

它採用1.5 - 1.7秒。

,當我嘗試

SELECT COUNT(categories.id), COUNT(serverfuncs.id) FROM categories, serverfuncs 

SELECT COUNT(categories.id), COUNT(clientfuncs.id) FROM categories, clientfuncs 

SELECT COUNT(clientfuncs.id), COUNT(serverfuncs.id) FROM clientfuncs, serverfuncs 

,它需要0.005 - 0.01秒。 (因爲它應該是)

有人可以解釋,這是什麼原因?

回答

6

你正在做的45個* 800個* 600行的交叉連接,你會發現,當你檢查的結果:-)

計數試試這個:

SELECT 
    (SELECT COUNT(*) FROM categories), 
    (SELECT COUNT(*) FROM serverfuncs), 
    (SELECT COUNT(*) FROM clientfuncs); 
+0

謝謝,它適合我 – therainycat

5

查詢是做cartesian product因爲沒有加入條件應用於這樣:

1 query : 800*600*45 = 21,6 mil 
2 query : 45*600  = 27 k 
3 query : 45*800 ... 
+0

感謝您的鏈接 – therainycat

+0

不用擔心,歡呼隊友:) – Stephan

2

這是因爲你的查詢連接表(查詢的最後部分中的逗號簡寫聯接)RA而不是單獨計算它們。所以只有兩個表的查詢會更快。

2

首先,你真的想在FROM子句中使用三個表來計算特定於每個表的計數嗎?這將導致SELECT語句生成三個表的笛卡爾乘積,這將導致計算總數的行數爲45 x 800 x 600。因此,許多categories.id值的重複值將被計數,其他值也會被計數。在任何情況下,如果您在FROM子句中使用前兩個表,笛卡爾產品將只包含45個X 800行,遠小於三個表生成的行數。因此,有兩個表的查詢要快得多。主鍵在這種情況下是沒有用的。

更好地使用三個不同的語句從每個表中獲取計數。如果您的RDBMS不支持FROM子句中的SELECT語句

SELECT (SELECT COUNT(categories.id) FROM categories), 
     (SELECT COUNT(serverfuncs.id) FROM serverfuncs), 
     (SELECT COUNT(clientfuncs.id) FROM clientfuncs); 

如果你仍然堅持在一個鏡頭讓計數,你可以使用下面的語法。這些會給出正確的數字,並且會非常快。