我应该索引什么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).