我应该索引什么mysql?
What should I index mysql?
我希望加快此查询的速度。我目前在
上有一个索引
users_score.appID
app_names.name
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM users_scores
RIGHT JOIN app_names ON app_names.id = users_scores.appID
WHERE app_names.name = "testapp1"
ORDER BY users_scores.score DESC
LIMIT 0 , 30
你的主键有索引吗? (users_score.id
,或您为其命名的任何名称)。如果不是,则应始终对键进行索引……事实上,它们就是索引。 app_names.id
也应该是主要的 key/index.
appID 是一个很好的索引,但我看到您通过名称搜索应用程序。如果 MySQL 不必对 WHERE
子句执行字符串比较,速度会更快。搜索 AppID 会更高效。鉴于应用程序名称已知 ('testapp1'),您可以在搜索前进行内部查询以确定 ID,如下所示。
WHERE app_names.id = (SELECT id FROM app_names WHERE app_names.name = "testapp1")
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM users_scores
RIGHT JOIN app_names -- Probably forces app_names to be first
ON app_names.id
= users_scores.appID -- users_scores second; Step 1
WHERE app_names.name = "testapp1" -- app_names first; Step 1
ORDER BY users_scores.score DESC
LIMIT 0 , 30
app_names 需要 INDEX(name)
users_scores 需要 INDEX(appID)
即使您删除 RIGHT
(这可能是噪音),优化器也会首先选择 app_names
,因为 WHERE
子句仅提及 app_names
。
所有这些以及更多内容都可以在我的 Creating an Index from a SELECT 博客中找到。
你不应该使用 RIGHT JOIN
。任何 RIGHT JOIN
都可以而且应该写成 LEFT JOIN
.
无论如何,您的 WHERE
子句会自动将查询转换为 INNER JOIN
:
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM app_names
INNER JOIN users_scores
ON users_scores.appID = app_names.id
WHERE app_names.name = 'testapp1'
ORDER BY users_scores.score DESC
LIMIT 30
因为您没有从 app_names 返回任何数据,您可以使用子查询完全摆脱 JOIN:
SELECT username, avatar, score
FROM users_scores
WHERE appID = (SELECT id FROM app_names WHERE name = 'testapp1' LIMIT 1)
ORDER BY score DESC
LIMIT 30
MySQL先执行不相关的子查询,所以MySQL可以使用app_names上的索引进行搜索table,然后可以利用索引在 users_scores 上进行搜索和排序。
为获得最佳读取性能,在 user_scores(appID, score)
上添加多列索引以满足搜索和排序,或者使用更大的 覆盖索引:user_scores(appID, score, username, avatar)
.
我希望加快此查询的速度。我目前在
上有一个索引users_score.appID
app_names.name
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM users_scores
RIGHT JOIN app_names ON app_names.id = users_scores.appID
WHERE app_names.name = "testapp1"
ORDER BY users_scores.score DESC
LIMIT 0 , 30
你的主键有索引吗? (users_score.id
,或您为其命名的任何名称)。如果不是,则应始终对键进行索引……事实上,它们就是索引。 app_names.id
也应该是主要的 key/index.
appID 是一个很好的索引,但我看到您通过名称搜索应用程序。如果 MySQL 不必对 WHERE
子句执行字符串比较,速度会更快。搜索 AppID 会更高效。鉴于应用程序名称已知 ('testapp1'),您可以在搜索前进行内部查询以确定 ID,如下所示。
WHERE app_names.id = (SELECT id FROM app_names WHERE app_names.name = "testapp1")
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM users_scores
RIGHT JOIN app_names -- Probably forces app_names to be first
ON app_names.id
= users_scores.appID -- users_scores second; Step 1
WHERE app_names.name = "testapp1" -- app_names first; Step 1
ORDER BY users_scores.score DESC
LIMIT 0 , 30
app_names 需要 INDEX(name)
users_scores 需要 INDEX(appID)
即使您删除 RIGHT
(这可能是噪音),优化器也会首先选择 app_names
,因为 WHERE
子句仅提及 app_names
。
所有这些以及更多内容都可以在我的 Creating an Index from a SELECT 博客中找到。
你不应该使用 RIGHT JOIN
。任何 RIGHT JOIN
都可以而且应该写成 LEFT JOIN
.
无论如何,您的 WHERE
子句会自动将查询转换为 INNER JOIN
:
SELECT users_scores.username, users_scores.avatar, users_scores.score
FROM app_names
INNER JOIN users_scores
ON users_scores.appID = app_names.id
WHERE app_names.name = 'testapp1'
ORDER BY users_scores.score DESC
LIMIT 30
因为您没有从 app_names 返回任何数据,您可以使用子查询完全摆脱 JOIN:
SELECT username, avatar, score
FROM users_scores
WHERE appID = (SELECT id FROM app_names WHERE name = 'testapp1' LIMIT 1)
ORDER BY score DESC
LIMIT 30
MySQL先执行不相关的子查询,所以MySQL可以使用app_names上的索引进行搜索table,然后可以利用索引在 users_scores 上进行搜索和排序。
为获得最佳读取性能,在 user_scores(appID, score)
上添加多列索引以满足搜索和排序,或者使用更大的 覆盖索引:user_scores(appID, score, username, avatar)
.