我不是MySQL索引的专家,但我看到了很多教程,使用PHP仍然需要7秒才能加载。
我在MySQL表中有大约50k行和30列。
如何提高MySQL获取数据的速度?我可以在下面的查询中改进一下吗?
SELECT tmdb_movies.movie_title,tmdb_movies.budget,tmdb_movies.original_language,tmdb_movies.original_title
,translations.translations_english_name
,videos.videos_name,videos.videos_key
FROM tmdb_movies
LEFT JOIN
(
SELECT
translations_tmdb_id
,GROUP_CONCAT(DISTINCT translations.translations_english_name SEPARATOR ', ') AS translations_english_name
FROM translations
GROUP BY translations_tmdb_id
) translations ON translations.translations_tmdb_id = tmdb_movies.tmdb_id
LEFT JOIN
(
SELECT
videos_tmdb_id
,GROUP_CONCAT(DISTINCT videos.videos_name) as videos_name
,GROUP_CONCAT(DISTINCT videos.videos_key) as videos_key
FROM videos
GROUP BY videos_tmdb_id
) videos ON videos.videos_tmdb_id = tmdb_movies.tmdb_id
Where tmdb_movies.tmdb_id= '$tmdb_id'
在这里,我使用tmdb_id
连接所有表。 tmdb_id
,translations_tmdb_id
和videos_tmdb_id
已在MySQL中编入索引。
以下是我的MySQL表结构示例:
tmdb_movies
表格:
tmdb_id movie_title
1 Logan
2 Iron Man
3 Superman
translations
表格
translations_tmdb_id translations_english_name
1 English
1 Hindi
1 French
2 English
2 Spanish
2 Hindi
videos
表格
videos_tmdb_id videos_name
1 Official Trailer
1 Trailer 2
2 Trailer 1
2 Trailer 2 HD
3 Superman Trailer 1
3 Superman Trailer 2
答案 0 :(得分:2)
您的主SELECT
声明可能没问题;你正在过滤自动增量主键。
这是两个子查询,其机会可能在于提高绩效。
第一个:
SELECT
translations_tmdb_id,
GROUP_CONCAT( DISTINCT translations.translations_english_name
SEPARATOR ', ') AS translations_english_name
FROM translations
GROUP BY translations_tmdb_id
translations_tmdb_id, translations_english_name
上的compound index (sometimes called a composite index or multi-column index)有可能帮助这个子查询。为什么?它可以帮助查询的GROUP BY
和DISTINCT
部分。
第二个:
SELECT
videos_tmdb_id
,GROUP_CONCAT(DISTINCT videos.videos_name) as videos_name
,GROUP_CONCAT(DISTINCT videos.videos_key) as videos_key
FROM videos
GROUP BY videos_tmdb_id
同样的原则适用,但两个不同的DISTINCT
条款会使事情变慢一些。在videos_tmdb_id, videos_name, videos_key
上尝试复合索引。它应该有所帮助。
答案 1 :(得分:2)
GROUP_CONCAT(DISTINCT ...)
?没有重复。这是您的查询重写:
SELECT
m.movie_title,
m.budget,
m.original_language,
m.original_title,
t.translations_english_names,
v.videos_names,
v.videos_keys
FROM tmdb_movies m
CROSS JOIN
(
SELECT
GROUP_CONCAT(translations_english_name SEPARATOR ', ') AS translations_english_names
FROM translations
WHERE translations_tmdb_id = @tmdb_id
) t
CROSS JOIN
(
SELECT
GROUP_CONCAT(videos_name ORDER BY videos_name) as videos_names,
GROUP_CONCAT(videos_key ORDER BY videos_name) as videos_keys
FROM videos
WHERE videos_tmdb_id = @tmdb_id
) v
WHERE m.tmdb_id = @tmdb_id;
这些是您应该使用的索引:
create index idxm on tmdb_movies(tmdb_id); -- if tmdb_id is PK, you have this already
create index idxt on translations(translations_tmdb_id, translations_english_name);
create index idxv on videos(videos_tmdb_id, videos_name, videos_key);