2011-09-30 33 views
0

我知道以下查詢返回相同的:當T1有多個T2且條件爲T2時,將T2連接到T1而不是T1到T2會更有效嗎?或者它是一樣的?

SELECT `cimgs`.* 
FROM `cimgs` 
INNER JOIN `cimgs_tags` ON `cimgs_tags`.`cimg_id` = `cimgs`.`id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

SELECT `cimgs`.* 
FROM `cimgs_tags` 
INNER JOIN `cimgs` ON `cimgs`.`id` = `cimgs_tags`.`cimg_id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

但是,乍一看我要說的是,第一個複製的cimgs表中的每個標籤的檢查條件下,當第二個檢查條件之前然後它加入相應的表...

雖然我不知道MySQL是否自動檢測並優化這些查詢,並且這兩個查詢有類似的性能?

+1

這是優化的工作... –

+0

那麼你應該做的基準測試,但是從我讀過的第一個應用的優化將重新排序聯接爲最有效。在只有兩張桌子的情況下,我無法想象即使沒有優化程序,它也會有所作爲... –

回答

3

查詢優化器將爲您執行此操作。它將使用索引統計信息,您應該跟上ANALYSE TABLE。不過,您可以使用STRAIGHT_JOIN強制te連接順序,並且您也可以強制使用某些索引。

你可以做一個解釋:

EXPLAIN SELECT `cimgs`.* 
FROM `cimgs` 
INNER JOIN `cimgs_tags` ON `cimgs_tags`.`cimg_id` = `cimgs`.`id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

EXPLAIN SELECT `cimgs`.* 
FROM `cimgs_tags` 
INNER JOIN `cimgs` ON `cimgs`.`id` = `cimgs_tags`.`cimg_id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

看到的差異。

Offcourse,對於LEFT JOIN或RIGHT JOIN,存在語義差異。

+0

謝謝!我很擔心這可能會導致未來有很多記錄的問題。 – Zequez

0

我相信this question

回答你的問題。

「對於內部聯接,順序並不重要。
對於外連接的順序很重要。
如果要強制按一定順序,您可以使用STRAIGHT_JOIN。」

3

從INNER JOINS無所謂。以相同的方式同樣沒有WHERE子句爲了

WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

WHERE (cimgs.id != 1) AND `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) 
  • 優化器知道這
  • SQL是聲明不是程序。也就是說,你說「什麼」和優化器決定「如何」
+1

你說「什麼」和優化器決定「如何」。這就是它應該如何工作的。在現實生活中,優化器有時犯了可怕的錯誤,你必須稍微踢一下。 – Thilo

+0

@Thilo:查詢變得更復雜,是的。通常這是因爲優化者是基於成本的:可能需要2周才能找到完美的計劃,因此它「足夠好」。這可能不是當然。第二個猜測優化器當時只適用於數據,索引,分佈等,雖然 – gbn

+0

「僅適用於當時的數據,索引,分佈等,並且可能不會持續」。是。這是一個棘手的問題。我不希望優化器爲複雜的查詢或偏斜的數據做好準備。我的問題是,一旦你達到了聲明式方法失敗的地步,你就很難強制系統用提示或類似方式「表現」。很高興有一個「程序化」的SQL替代方案,你可以明確地列出你想要的執行計劃。如果一個糟糕的執行計劃只是慢了2倍,那麼這都不是真正的問題,但它可能是1000倍。 – Thilo

相關問題