当执行 ORDER BY 和执行 COUNT 时,MySQL 查询永远不会完成

标签 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

最佳答案

当遇到查询性能问题时,您应该做的第一件事是对查询运行解释(只需在 select 语句前加上“explain”前缀,您就可以查看 https://dev.mysql.com/doc/refman/5.7/en/using-explain.html 了解更多详细信息。)虽然您可能认为您已经拥有了所有如果适当的索引到位,有时 DBMS 引擎做出的决策并不明显。如果您认为会使用索引的地方发现一个或多个全表扫描,请不要感到惊讶(这可能是“查询永远不会完成”问题的最常见来源)

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

关于当执行 ORDER BY 和执行 COUNT 时,MySQL 查询永远不会完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52528419/

相关文章:

mysql - 如何检查 SQL 中 VARCHAR(50) 列的值

mysql - SQL中的正则表达式检测一个或多个数字

MySQL LOAD_FILE 返回 NULL

mysql - 比较 MySQL 日期?

mysql - 如何在 codeigniter 中使用 where 和 join

sql - MySQL 通过查询转储

PHP使用mysql需要计算所有下拉框的总成本

php - Arch Linux 上 LAMP 中的 Codeigniter

php - 使用 PHP 导出 SQL 表

php - MySQL、PHP 和失败的 UPDATE 命令