2009-01-16 102 views
0

所以,首先,這裏是我的查詢:(注:我知道SELECT *是不好的做法,我剛換它使查詢更具可讀性緩慢的MySQL查詢 - 可能是索引問題?

SELECT pcln_cities.*,COUNT(pcln_hotels.cityid) AS hotelcount 
    FROM pcln_cities 
    LEFT OUTER JOIN pcln_hotels ON pcln_hotels.cityid=pcln_cities.cityid 
    WHERE pcln_cities.state_name='California' GROUP BY pcln_cities.cityid 
    ORDER BY hotelcount DESC 
    LIMIT 5 

所以我知道,要解決這樣的事情你添加解釋給查詢的開始,但我不是100%確定如何讀取結果,所以在這裏,他們是:

alt text http://www.andrew-g-johnson.com/query-results.JPG

獎勵積分,告訴我要尋找什麼,在解釋一個答案結果

編輯的城市表有以下指標(或者是指數?)

  • cityid
  • STATE_NAME
  • ,我只是增加了一個既因爲我認爲這可能幫助(它沒「T)

酒店的表有以下指標(或者是指數?)

  • cityid
+0

有關數據類型和索引位置的額外信息會很好。 – Tomalak 2009-01-16 14:43:59

回答

3

嗯,有什麼不是很正確的查詢。 你使用一個聚合函數(count),但你只需通過id進行分組。 通常,您應該對選擇列表中的所有列進行分組,這些列不是聚合函數。

正如你現在指定的查詢,恕我直言,在DBMS不能準確地確定哪些值,他應該顯示那些非集合列...

這將是更正確的,如果您的查詢如下所示:

select cityname, count(*) 
from city inner join hotel on hotel.city_id = city_id 
group by cityname 
order by count(*) desc 

如果您沒有cityName的索引,並且您在城市名稱上過濾,那麼如果您在該列上放置索引,它將提高性能。

簡而言之:在您經常用於過濾或排序的列上添加索引可能會提高性能。如果你更新或插入一條記錄,請記住,如果你更新或插入一條記錄,你可以使用它作爲'指南',但每種情況都不同,有時可以添加一個跨越多列的索引。 ,索引也需要更新,所以在添加/更新/刪除記錄時存在一定的性能成本)

可以提高性能的另一件事是使用內部聯接而不是外部聯接。我不認爲有必要在這裏使用外部連接。

+0

很好,我修改了這一個,現在我們返回結果<1秒 - 謝謝! – 2009-01-16 15:13:29

0

它看起來像你沒有對pcln_cities.state_name索引或pcln_cities.cityid?嘗試添加它們。

鑑於您已經更新了您的問題,並說您確實擁有這些索引,我只能建議您的數據庫目前在加利福尼亞州擁有絕大多數城市,因此查詢優化程序認爲它可以更容易地執行表格掃描並丟棄非加利福尼亞州的數據,而不是使用索引來挑選加州數據。

+0

試過了,無濟於事 – 2009-01-16 14:50:49

0

你的查詢看起來不錯。有什麼其他東西可以鎖定您需要的記錄嗎?桌子特別大嗎?我懷疑數據是問題,因爲沒有那麼多酒店...

我跑到類似的問題與MySQL。花了一年多的時間進行調整,打補丁,並認爲我是一個SQL dummy,我切換到SQL Server Express。具有完全相同數據的完全相同的查詢將在SQL Server Express中運行速度提高2-5個數量級。對於複雜度適中的查詢(5+表),MySQL似乎特別困難。我認爲在SUN收購該組織之後,MySQL優化器變得遲鈍...

+0

〜8000行在城市,〜42000在酒店 – 2009-01-16 15:02:19