我该怎么索引mysql?

时间:2015-03-09 07:00:56

标签: mysql performance indexing

我正在寻求加快此查询速度。我目前有一个索引

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

3 个答案:

答案 0 :(得分:1)

您的主键上有索引吗? (users_score.id或其他任何名称)。如果没有,键应该始终被索引...实际上,它们是索引。 app_names.id也应该是主键/索引。

appID是一个很好的索引,但我看到你通过名称搜索应用程序。如果MySQL不必对WHERE子句进行字符串比较,速度会更快。搜索AppID会更有效率。鉴于应用名称已知(' testapp1'),您可以执行内部查询以在搜索之前确定ID,如下所示。

WHERE app_names.id = (SELECT id FROM app_names WHERE app_names.name = "testapp1")

答案 1 :(得分:0)

你永远不应该使用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表上的索引进行搜索,然后能够利用users_scores上的索引进行搜索和排序。

为获得最佳读取性能,请在user_scores(appID, score)上添加多列索引以满足搜索和排序,或者使用更大的覆盖索引user_scores(appID, score, username, avatar)。< / p>

答案 2 :(得分:-1)

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的博客中找到。