我無法找到爲什麼我的查詢速度非常慢;在雙至強L5630與48GB DDR3運行Ubuntu 16.04與PHP7.0-FPM和MariaDB的60秒10.0.27極慢的特定表的左加入
SELECT v.video_id, v.user_id, v.title, v.slug, v.rating, v.rated_by,
v.duration, v.thumb, v.total_views, v.total_comments, v.add_time,
v.view_time, v.status, v.source_id, v.orientation, v.thumbs,
v.featured, v.flagged,
u.username,
s.name,
f.reason,
GROUP_CONCAT(c.name) AS categories
FROM video AS v
LEFT JOIN video_flags AS f ON (f.video_id = v.video_id)
LEFT JOIN video_sources AS s ON (s.source_id = v.source_id)
LEFT JOIN user AS u ON (u.user_id = v.user_id)
LEFT JOIN video_category AS vc ON (vc.video_id = v.video_id)
LEFT JOIN video_categories AS c ON (c.category_id = vc.category_id) GROUP BY v.video_id ORDER BY v.video_id DESC LIMIT 10
我已經精確定位問題是在video_flags表,因爲當我的評論f.reason字段和video_flags上的左連接,查詢只需要152ms。該video_flags表對VIDEO_ID索引和字段類型是在兩個表INT相同(11)
當我運行解釋選擇,我得到以下回:
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+---------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+---------+-------------------------------------------------+
| 1 | SIMPLE | v | ALL | NULL | NULL | NULL | NULL | 1219933 | Using temporary; Using filesort |
| 1 | SIMPLE | f | ALL | video_id | NULL | NULL | NULL | 1 | Using where; Using join buffer (flat, BNL join) |
| 1 | SIMPLE | s | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.v.source_id | 1 | |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.v.user_id | 1 | |
| 1 | SIMPLE | vc | ref | video_id | video_id | 4 | adb_network.v.video_id | 2 | Using index |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.vc.category_id | 1 | Using where |
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+---------+-------------------------------------------------+
我不知道是什麼我在這裏失蹤,首先我認爲它必須有一些video_flags表爲空,然後我添加了一條記錄,並且查詢很快(200毫秒),但現在問題又回來了,並且查詢正在永久完成。
任何幫助,非常感謝。
更新:加入而不f.reason列@somnium的解釋中進行選擇:
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+------+-------------+
| 1 | SIMPLE | v | index | NULL | PRIMARY | 4 | NULL | 5 | |
| 1 | SIMPLE | f | ref | video_id | video_id | 4 | adb_network.v.video_id | 1 | Using index |
| 1 | SIMPLE | s | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.v.source_id | 1 | |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.v.user_id | 1 | |
| 1 | SIMPLE | vc | ref | video_id | video_id | 4 | adb_network.v.video_id | 2 | Using index |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | adb_network.vc.category_id | 1 | Using where |
+------+-------------+-------+--------+---------------+----------+---------+----------------------------+------+-------------+
解:由於@somnium建議我嘗試添加上的FORCE INDEX
video_id
列,並且將查詢時間從60秒降至272ms - 仍然不確定爲什麼它會在連接期間丟失索引,但問題得到解決。謝謝
SELECT v.video_id, v.user_id, v.title, v.slug, v.rating, v.rated_by,
v.duration, v.thumb, v.total_views, v.total_comments, v.add_time,
v.view_time, v.status, v.source_id, v.orientation, v.thumbs,
v.featured, v.flagged,
u.username,
s.name,
f.reason,
GROUP_CONCAT(c.name) AS categories
FROM video v
LEFT JOIN video_flags f FORCE INDEX FOR JOIN (video_id) ON (f.video_id = v.video_id)
LEFT JOIN video_sources s ON (s.source_id = v.source_id)
LEFT JOIN user u ON (u.user_id = v.user_id)
LEFT JOIN video_category vc ON (vc.video_id = v.video_id)
LEFT JOIN video_categories c ON (c.category_id = vc.category_id) GROUP BY v.video_id ORDER BY v.video_id DESC LIMIT 10
您的視頻表中有1219933,並且您將其加入到其他幾個表中。您在此表上沒有任何過濾器,因此所有這些行都用於這些多個聯接中。 60秒聽起來非常好。但是,如果您還沒有 – e4c5
感謝您的評論,您可以嘗試在video_id上添加索引。奇怪的是我的查詢執行多個連接,問題只發生在包含f.reason列的時候,如果我發表評論,查詢只需120ms,所有其他連接仍然完好無損。 video_flags.video_id上有一個索引,因此不應該是 – Hugo
這個問題,並且您意識到您應該聚合SELECT中未分組的所有列?否則MySQL允許,但這是不好的做法。 –