2011-10-02 99 views
4

我想優化這個查詢(因爲子查詢通常不是很快),但是我迷路了,因爲我不能使用連接來重寫這個,這樣會更好地提高性能,你能幫助我嗎?MySQL優化子查詢

SELECT id, company, street, number, number_addition, postalcode, telephone 
FROM clients 
    WHERE (postalcode BETWEEN '1000' AND '9000') AND street = (
     SELECT DISTINCT street FROM clients WHERE (postalcode BETWEEN '1000' AND '9000') AND postalcode <= (
      SELECT MIN(postalcode) FROM clients WHERE street = 'Main Street' AND  (postalcode BETWEEN '1000' AND '9000')) 
     ORDER BY postalcode DESC LIMIT 1, 1) 
ORDER BY postalcode DESC, street DESC, number DESC, number_addition DESC, telephone DESC 
LIMIT 1 

感謝您的時間傢伙。

+0

這個查詢真的很慢嗎?不要隨意優化。在您的MySQL服務器中啓用* slow_query_log *。這會在* slow_query_log_file *中記錄超過* long_query_time *的查詢。 – 2011-10-02 12:15:41

回答

1

SELECT DISTINCT street ORDER BY postalcode沒有意義的(我認爲是無效的ANSI SQL),除非postalcode在功能上依賴於street哪位,我不認爲它是,因爲你的GET-最低郵編-ON-如果是的話,Main-Street的內部子選擇就沒有意義了。 MySQL會讓你擺脫它,但結果會不一致。你想在這裏說什麼?

我不認爲這應該是特別慢,因爲你有什麼不是一個依賴的子查詢;子查詢只執行一次,而不是每個外部行重複執行。您可以將其重寫爲三個單獨的查詢 -

  1. 獲得Main Street上的最低郵政編碼;
  2. 獲得街道第二高郵政編碼低於(1)(不一致);
  3. 瞭解街道上客戶的詳細情況(2)。

執行沒有區別。 (事實上​​,它可能是更好的清晰度這樣做。),

可以重寫這些使用作爲連接自左聯接上,低於爲空,以獲得最小值/最大值,但我不認爲你會因爲這個例子而獲得任何東西,並且考慮到兩個級別的加入和第二高要求,它會變得非常混亂。這個查詢在實踐中特別慢嗎? EXPLAIN是什麼樣的?你有索引postalcodestreet

+0

SELECT DISTINCT street ORDER BY postalcode - 事情是我有一張桌子的客戶,我想要在這張桌子上的所有街道。每條街道都可以有多個郵政編碼,所以我想選擇郵政編碼的最低值,然後按這個順序排列街道。 – Joseph

+0

我無法在生產環境中測試它,但是由於這是一個在應用程序前端運行的查詢(很少),我認爲這樣做會是一個好主意,但是如果你認爲它比我好,我會等待它在生產中的運行方式。順便說一句,郵政編碼和街道索引。謝謝你的時間。 – Joseph

+0

您不是通過最小郵政編碼訂購街道,而是通過每條街道的一個隨機郵政編碼訂購。其他數據庫會將此標記爲錯誤,因爲這通常是一個錯誤。嘗試'SELECT街道... GROUP BY街道ORDER BY MIN(郵政編碼)'。 – bobince