执行ORDER BY和COUNT

时间:2018-09-27 02:10:32

标签: mysql sql

我正在尝试计算表格中的字符等级。无论出于何种原因,只要我使用order by子句运行查询,查询就会永远运行。

我有一个非常类似的查询,该查询在具有不同架构的不同服务器中运行,但它实际上是在做相同的事情,并且几乎立即完成。我完全不知道为什么这个查询永远不会完成并永远花费。

我正在索引字符表中的几乎所有内容,但仍然没有运气。

KEY `accountid` (`accountid`),
KEY `party` (`party`),
KEY `ranking1` (`level`,`exp`),
KEY `ranking2` (`gm`,`job`),
KEY `idx_characters_gm` (`gm`),
KEY `idx_characters_fame` (`fame`),
KEY `idx_characters_job` (`job`),
KEY `idx_characters_level` (`level`),
KEY `idx_characters_exp` (`exp`),

当我不包括ORDER BY时,它运行得很好,并且立即完成。当我这样做时,它将永远运行。

数据库中只有28,000个字符,因此计算排名并不需要那么密集,尤其是当限制只有1个时。

SELECT c.name
    , 1+(
      SELECT COUNT(*)
      FROM msd.characters as rankc
      WHERE rankc.level > c.level 
      LIMIT 1
    ) as jobRank
FROM characters as c
JOIN accounts as a
ON c.accountid = a.id
WHERE c.gm = 0 AND a.banned = 0
ORDER BY c.`level` DESC, c.exp DESC
LIMIT 1
OFFSET 0;

任何帮助将不胜感激!

编辑:

基本上,每个角色都有一个独特的工作,我希望获得该角色的工作排名。排名的默认顺序是按级别。这就是为什么我要在jobRank SELECT中进行比较。

以下是我想要的结果的一个示例:desired result

1 个答案:

答案 0 :(得分:0)

遇到查询性能问题时,您应该做的第一件事是对查询运行解释(仅在select语句前加上“ explain”,您可以看到https://dev.mysql.com/doc/refman/5.7/en/using-explain.html以获得更多详细信息。)虽然您可能会认为自己拥有所有适当的索引,有时DBMS引擎做出的决策不会很明显。在您认为将使用索引的地方进行一次或多次全表扫描,不要感到惊讶(这可能是“查询永不完结”问题的最常见来源)

更新:根据您的解释输出,该查询正在子查询中执行多个全表扫描,这可能是您的性能问题。您想尝试使用索引来获取该子查询,所以我建议从子查询中删除LIMIT 1(where子句过滤掉了您不需要的级别,并且没有group by子句,因此应该只返回1行)看看是否能胜任工作。