[英]SQL Slow Loading Time
我有以下代碼,並且在表tblfollowers
中只有幾個follower_id
或username
時,它會很好地加載。
但是,一旦載入成千上萬種,它的加載速度就會非常緩慢。
有沒有更好的方法來寫這個?
我在它加入的字段上添加了索引,但這似乎沒有什么不同。
$scheduler->render_table("events
LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username
WHERE events.status ='active'
AND((tblfollowers.follower_id)='$test') OR ((events.id_user) ='$test')
GROUP BY events.event_id, events.event_name, events.user_name, events.id_user, events.time, events.details, events.location, events.dresscode
ORDER BY events.timestamp DESC"
,"event_id","start_date, start_date,event_name,details");
$scheduler->render_sql("SELECT event_id, start_date, end_date, event_name, details
FROM events ");
這是此查詢的說明:
1 SIMPLE events ALL NULL NULL NULL NULL 1593 Using where; Using temporary; Using filesort 1 SIMPLE tblfollowers ref PRIMARY PRIMARY 4 dbhappps.events.id_user 17 Using where; Using index
這是桌子
大段引用
表事件:
event_id int(11) Primary Unique Index
event_name varchar(400)
user_name varchar(155)
id_user int(11) Primary Unique Index
start_date datetime
end_date datetime
details varchar(700)
location varchar(255)
dresscode varchar(255)
timestamp timestamp on update CURRENT_TIMESTAMP
大段引用
tblfollowers:
username int(11) primary
follower_id int(11) primary
timestamp timestamp on update CURRENT_TIMESTAMP
如何加快查詢速度?
您在group by
僅需要兩個字段(如果字段event_id
是主鍵,則只需要該字段。
使用分組依據來考慮較少的字段將使您的查詢更快。
您應該只將功能獨立的字段放在分組依據中,列出功能相關的字段,這是毫無意義的,而且浪費時間。
幸運的是,MySQL不需要您執行此操作。
$scheduler->render_table("events
LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username
WHERE events.status ='active'
AND '$test' IN (tblfollowers.follower_id, events.id_user) <<-- maybe faster
GROUP BY events.event_id, events.id_user <<-- only include unique key fields
ORDER BY events.timestamp DESC"
,"event_id","start_date, start_date,event_name,details");
$scheduler->render_sql("SELECT event_id, start_date, end_date, event_name, details
FROM events ");
詳情請參閱此處: http : //rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html
為什么慢呢?
沒有tblfollowers和事件的表定義,這很難說。
使用說明
如果要查看瓶頸所在,請在選擇前面放置一個EXPLAIN
,然后將結果粘貼到您的問題中。
$scheduler->render_sql("EXPLAIN SELECT event_id, start_date, end_date, event_name, details
FROM events ");
修改索引無濟於事
使用explain
的輸出來告知您的決定,添加索引會減慢插入和更新的速度,並會使磁盤使用量大大增加。
這主要是一個臨時文件,會使您的查詢變慢。 EXPLAIN
的“ temporary
”一詞意味着,每次運行該查詢時,MySQL服務器都必須創建一個臨時表。 雖然很小,但它保存在內存中,因此速度相對較快。 當它變得足夠大時,它會移到磁盤上,並使查詢的運行速度變慢。
什么時候使用臨時表? 在《 MySQL參考手冊-優化數據庫結構》中對此進行了很好的描述。 就您而言,這一定是在發生,因為您是按字段timestamp
排序的,而該timestamp
不包含在GROUP BY
子句中。
接下來,您是否真的需要按所有這些領域分組? 由於您要按events
表的主鍵進行分組,因此按另一個event
的字段進行分組是沒有意義的。 嘗試執行以下查詢:
$scheduler->render_table("events
LEFT JOIN tblfollowers ON events.id_user = tblfollowers.username
WHERE events.status = 'active'
AND tblfollowers.follower_id = '$test'
OR events.id_user = '$test'
GROUP BY events.event_id, events.timestamp
ORDER BY events.timestamp DESC"
, "event_id", "start_date, start_date, event_name, details");
編輯:順便說一句,您是否忘了在條件周圍加上括號? AND
優先於OR
。
WHERE events.status ='active'
AND (tblfollowers.follower_id='$test' OR events.id_user='$test')
這樣對我來說似乎更合乎邏輯。
完全披露:我不了解PHP。
但是,嘗試拆分查詢並使用UNION
將其重新組合在一起。 我認為,是OR
會阻止您使用索引,從而影響您的性能。 這就是我認為您的查詢在PHP之外的樣子。
SELECT event_id
, start_date
, end_date
, event_name
, details
FROM events
LEFT JOIN tblfollowers
ON events.id_user = tblfollowers.username
WHERE events.status ='active'
AND tblfollowers.follower_id = '$test'
UNION
SELECT event_id
, start_date
, end_date
, event_name
, details
FROM events
WHERE id_user = '$test'
沒有create table語句很難說。
對於該分組依據和排序依據。 如果event_id不是主要對象,則可以通過在event_id(時間戳記desc)上添加復合索引來看到一些改進。 如果按event_id排序,則可接受timestamp desc,這樣可以節省您一些時間。 組通過執行隱式順序來進行重新排序,這樣會使事情變慢。 按event_id,時間戳ASC進行分組,然后按時間戳DESC進行排序,對於該排序可能會遇到最壞的情況。
如果event_id是主要的,則在時間戳DESC上添加索引將創建event_id和timstamp DESC的復合索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.