2012-06-10 116 views
2

我有以下查詢從MySQL(所有InnoDB的)選擇的用戶和他們的位置,等等。表userblocked_userblocked_countries具有大約2密耳行,每行,countries約250,regions約3500和cities約2.8mil。MySQL查詢優化

問題是查詢速度很快(0.05秒),而WHERE子句中沒有AND co.country_id='us'。然而,我嘗試過這麼多,但只是覺得這個查詢肯定有一個更容易和更好的方法,不是嗎?

我錯過了什麼?任何幫助,高度讚賞!非常感謝您提前!

+0

並與where子句中的contry_id是怎麼慢? – Sebas

+0

@Sebas:我還沒有想出,因爲有些分鐘後,我每... – Chris

+0

OK,一個問題的時候停止操作:爲什麼您使用左聯接?你知道,通過在where子句中添加一個等式來將左連接轉換爲內連接嗎?你對co.country_id =「我們」是影響您的發言留給國表 – Sebas

回答

2

再次感謝你的幫助。最後,我找到了解決問題的方向。性能問題主要是由於範圍掃描和ORDER BY ... LIMIT之間的混合造成的。因此,我學到了很多關於索引的(對我而言是新的),並發現如果你有一個範圍掃描(在我的情況下,年齡在x和y之間),那麼測距列必須是最後一個串聯索引,否則索引不能完全使用。另外,用於對結果進行排序的列必須位於索引中的最後一列。所以,給定範圍掃描和ORDER BY之間的混合,你需要決定是否應該使用索引進行排序或選擇。

在我的情況下,它意味着爲幾個索引考慮一些很好的組合,其中要排序的剩餘行數僅僅是很少的,或者如果搜索不能縮小到僅僅一些行,則將會是單獨的索引用於排序,因爲查詢將很快找到LIMIT給出的行數。

1

嘗試改變WHERE到具有用於COUNTRY_ID

AND birthdate <= '802726152' 
AND birthdate >= '676495752' 

ORDER BY u.id DESC 
HAVING co.country_id='us' 
LIMIT 20 
+1

'HAVING'子句用於比較以某種方式進行彙總的值,而不是添加其他篩選。 – judda

+0

我相信你已經在downvoting我的文章之前測試過了嗎?我會建議這樣做。 MySQL的網站將確認以下內容:「WHERE子句用於限制記錄,並且 查詢優化器也使用它來確定要使用哪些索引和表。HAVING 是最終結果集上的」過濾器「,並在應用於ORDER BY和 GROUP BY,所以mysql不能用它來優化查詢。「之所以我不需要它來優化查詢,是因爲OP說它已經在沒有國家的情況下運行得很快,所以通過在事後使用HAVING,他保持了他的速度 – Bryan

+0

@BryanMoyles:感謝Bryan的幫助。事實上,使用'HAVING'的速度會更快,可能是因爲MySQL不會使用'country_id'作爲關鍵字,正如您所提到的......儘管如此,它仍需要幾秒鐘的時間,但是再次感謝您! :) – Chris