[英]MySQL Query optimisation
我目前正在一個需要一些優化的網站上工作...因為首頁加載大約需要15-20秒,所以我認為進行一些優化會很好。
這是出現在MySQL慢查詢日志中的一個查詢:
SELECT a.user,a.id
FROM `profil_perso` pp
INNER JOIN `acces` a ON pp.parrain = a.id
INNER JOIN `acces` ap ON ap.id = pp.id
WHERE pp.parrain_visibilite = '1'
AND a.actif = 1
GROUP BY a.id
ORDER BY ap.depuis DESC LIMIT 15;
在profil_perso
(約20.7萬行-包含電子郵件和配置文件)上,有perso_id
作為主鍵,還有id
(外鍵)+ parrain
(引用)+ parrain_visibilite
(顯示引用)是索引。
在acces
有一個id
是主鍵,還有一個depuis(注冊日期)被索引了
基准實際上顯示了這一點:
第一次:1.94532990456
上次:1.94532990456
平均時間:0.0389438009262
我試圖這樣說:
SELECT DISTINCT a.id, a.user
FROM `profil_perso` pp
LEFT JOIN `acces` a ON pp.parrain = a.id
WHERE pp.parrain_visibilite = 1
AND a.actif = 1
AND pp.id != 0
ORDER BY pp.id DESC LIMIT 15;
基准仍然顯示以下內容:
第一次:1.96376991272
上次:1.96376991272
平均時間:0.0393264245987
有任何減少查詢時間的提示嗎?
這是完整的索引:
訪問:
id (primary)
derniere_visite -- last visit
pays_id -- country_id
depuis -- registration time
perso_id -- foreign key to profil_perso primary key
actif -- account status
compte_premium -- if account is premium
profil_perso:
perso_id (primary)
id -- foreign key to acces primary key
genre -- gender
parrain_visibilite -- visibility of referer
parrain -- referer
parrain_contexte
telephone
orientation
naissance -- birthdate
photo -- if it has a picture
運行EXPLAIN SELECT DISTINCT a.id .....;
這將幫助您顯示可能缺少索引的位置等。
為什么在這里有兩個JOIN
?
在acces (actif, depuis)
上創建一個復合索引:
CREATE INDEX ix_acces_actif_depuis ON acces (actif, depuis)
,在profil_perso (parrain, parrain_visibilite)
上創建一個復合索引:
CREATE INDEX ix_profilperso_parrain_parrainvisibilite ON profil_perso (parrain, parrain_visibilite)
並嘗試這個:
SELECT a.user, a.id
FROM acces a
JOIN profil_perso p
ON pp.parrain = a.id
AND pp.parrain_visibilite = 1
WHERE a.actif = 1
ORDER BY
a.actif DESC, a.depuis DESC
LIMIT 15
這個查詢將使用索引上actif
避免排序,並在指數profil_perso
發現和過濾掉不可見parrain
的。
由於此處的LIMIT 15
,因此該查詢應該是即時的。
這也有助於了解您的actif
字段的選擇性。
為了解決這個問題,請運行:
SELECT COUNT(DISTINCT actif) / COUNT(*)
FROM acces
適當的應答者在很大程度上取決於模式的數據分布(記錄計數,字段的基數和字段組合等)以及查詢表達式。 即使提供了這些信息,我們也只能提供有關測試的建議,這只會帶來更多有關測試的建議。
但是我們可以從涉及表的表的第一個切口開始,再加上當前EXPLAIN的結果(twise,第二個和第一個結果)。
一般來說,您需要確保正確設置索引-不僅針對主鍵,而且還針對表聯接中使用的外鍵。
此外,通常最好為要過濾/排序的任何字段定義索引-因此,請再次確保正確設置了這些索引。
但是,我認為這里最大的性能問題可能是因為您正在對207k條記錄進行排序以檢索最后插入的15條記錄-您能以不同的方式實現相同的目標嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.