我一直在尝试构建一个庞大的查询,并且成功了,并且能够实际完成查询。 但是,我从开发环境(小型数据库)转到实时环境(大型数据库)测试,但遇到了性能问题。

我认为答案可以在这里找到: https : //dba.stackexchange.com/a/16376

但是真的没有其他办法了吗? 我什至将子查询放在VIEW中的原因是因为它们具有更复杂的构造。

VIEWS /查询示例:

pjl视图:

    (SELECT `pj`.`id` AS `id`,`pj`.`globalId` AS `globalId`,`pj`.`date` AS `date`,`pj`.`serverId` AS `serverId`,`pj`.`playerId` AS `playerId`,'playerjoins' AS `origin`
    FROM `playerjoins` `pj`) 
    UNION ALL 
    (SELECT `pl`.`id` AS `id`,`pl`.`globalId` AS `globalId`,`pl`.`date` AS `date`,`pl`.`serverId` AS `serverId`,`pl`.`playerId` AS `playerId`,'playerleaves' AS `origin`
    FROM `playerleaves` `pl`)

ll_below视图:

    SELECT `ll`.`id` AS `id`,`ll`.`globalId` AS `globalId`,`ll`.`date` AS `date`,`ll`.`serverId` AS `serverId`,`ll`.`gamemodeId` AS `gamemodeId`,`ll`.`mapId` AS `mapId`,`pjl`.`origin` AS `origin`,`pjl`.`date` AS `pjldate`,`pjl`.`playerId` AS `playerId`
    FROM `pjl`
    JOIN `levelsloaded` `ll` 
    ON `pjl`.`date` <= `ll`.`date`

现在很简单的查询:

    SELECT * FROM
    (
            (SELECT * FROM ll_below WHERE playerId = 976) llbelow
            INNER JOIN
            (SELECT id, MAX(pjldate) AS maxdate FROM ll_below WHERE playerId = 976 GROUP BY id) llbelow_inner
            ON llbelow.id = llbelow_inner.id AND llbelow.pjldate = llbelow_inner.maxdate
    )
    WHERE origin = 'playerjoins'
    ORDER BY date DESC

我可以将所有内容都放在一个大查询中,但是在我眼中却变得一团糟。

我也知道为什么性能如此之差,因为MySQL无法在pjl视图中使用MERGE算法,因为其中包含UNION ALL 如果我将WHERE playerId = 976子句放在正确的位置,那么性能影响就消失了,但是我还会有一个包含50行之类的查询。

如果我想要性能和仍然简洁的查询,有人可以建议我该怎么做吗?

===============>>#1 票数:1 已采纳

本条款:

WHERE origin ='playerjoins'

这意味着您根本不需要执行UNION,因为在查询结束时您没有使用pl的任何行。

您说对了,该视图可能会强制使用临时表,而不是使用合并算法。

UNION ALL还将创建自己的临时表。 根据Bug#50674 ,此情况在MySQL 5.7.3(在撰写本文时仍为Alpha版)中进行了优化, 请勿为UNION ALL创建临时表

另外,GROUP BY可能正在创建第三级临时表。

我看到您也在执行“ 每组最多n个”操作,以使行与每个id的最大日期匹配。 对于这种类型的操作,有不同的解决方案,它们不使用子查询。 例如,请参阅我的答案:

根据行数和其他条件,我已经看到,每组最多n个查询的两种解决方案都可以提供更好的性能。 因此,您应该测试这两种解决方案,并根据数据的状态和大小查看哪种方法更好。

我认为您应该解开视图,联合和子查询。 在进行联接和聚合之前,请查看是否可以对基础表直接应用各种WHERE条件(例如playerId=976 )。 这将大大减少检查行的数量,并避免由视图,联合和分组依据导致的临时表多层。


发表您的评论:

您似乎想要的查询是一个特定玩家每个级别的最新加入。

像这样:

SELECT ll.id, 
  ll.globalId,
  ll.date AS leveldate,
  ll.serverId,
  ll.gamemodeId,
  ll.mapId,
  pj.date AS joindate,
  pj.playerId
FROM levelsloaded AS ll
INNER JOIN playerjoins AS pj
  ON pj.date <= ll.date
LEFT OUTER JOIN playerjoins AS pj2
  ON pj.playerId = pj2.playerId AND pj2.date <= ll.date AND pj.date < pj2.date 
WHERE pj.playerId = 976
  AND pj2.playerID IS NULL
ORDER BY joindate DESC

(我尚未测试此查询,但它应该可以帮助您入门。)

===============>>#2 票数:0

比尔是绝对正确的……您的观点甚至没有真正提供任何好处。 我已经尝试为您构建一些东西,但是我的解释可能并不完全正确。 首先以简单的单词问自己,我想要得到什么。 这是我想出的。

我正在寻找一个玩家(因此您的玩家ID = 976)。 我也只考虑PLAYERJOINS实例(而不是淘汰联合部分的玩家离开)。 对于这个玩家,我想要他们最近加入游戏的日期。 从那个日期开始作为基准,我希望在最大日期或之后创建的所有“已加载的关卡”加入。

因此,第一个查询只不过是playerJoined表中玩家976的最大日期。 谁在乎其他任何人,或任何其他用户。 此处的ID与通过联接在LevelsLoaded表中获得的ID相同,因此,对于IMO而言,获得该玩家ID和同一个人的相同levelLoaded ID毫无意义。 然后,从同一人的最大日期/之后的加载级别中获取其余详细信息,以任何顺序进行排序。

如果我对您的查询的解释不正确,请提供明显的调整说明。

SELECT 
      ll.id,
      ll.globalId,
      ll.`date`,
      ll.serverId,
      ll.gamemodeId,
      ll.mapId,
      'playerjoins' as origin,
      playerMax.MaxDate AS pjldate
   FROM 
      ( SELECT MAX( pj.`date` ) as MaxDate
           FROM playerjoins pj 
           where pj.id = 976 ) playerMax
         JOIN levelsloaded ll 
            ON ll.id = 976
           AND playerMax.MaxDate <= ll.`date`

  ask by skiwi translate from so

未解决问题?本站智能推荐:

1回复

MySQL IN条件子查询

我有一个问题和答案列表,以及一个根据正确答案的百分比过滤问题的选项。 所以我在清单中使用以下查询: 并使用另一个查询来查找问题IDS,其正确答案的百分比在给定范围内。 查询如下: 现在的问题是,第二个查询将返回近4000个问题ID,并且在不久的将来会增加,并且可能会变成10k
3回复

在MYSQL查询中使用WHERE和ORDER BY条件时结果非常慢

我面临的问题非常缓慢。 我正在分享表结构和结果。 如果您有任何建议,请尽快更新。 ================================================== =============== 表结构 - https://www.phpmyadmin.ne
2回复

mysql fallback WHERE语句

假设我这样做: 在这种情况下,它将尝试执行field2 = '2019@162440'和field2 LIKE '%%2019@%%'条件的匹配(即,它将搜索与那些条件匹配的行,因此需要更多的计算能力尝试找到匹配两个条件的行,即使它已经找到匹配的field2 = '2019@162440
1回复

mysql-条件在vs条件在哪里

在没有结论的情况下,我对此测试和我的测试找不到明确的答案: 如果我在联接的表中有一列必须等于一个常数(或与另一个关系),将条件置于ON的速度更快吗? 还是在哪里结束? 例: 要么 我以为第一个版本应该更快,但我不确定。 有什么想法吗?
1回复

包含UNION的MySQL视图不能很好地优化...换句话说,慢!

我有一个包含UNION ALL的视图。 例如: 这些是大型表,每个表包含数百万行。 如果我写: 而不是立即,它基本上永远不会返回,因为针对此视图编写的其他查询。 如果我在针对各个基础表的查询中使用LIMIT,则它是立即的。 我在底层表上有索引。 似乎MySQL在应用任何
1回复

2GB以上可加快单个表上的SQL查询

我正在对MYSQL数据库中非常大的表中的广告收入进行查询。 它包含许多维度,例如设备类别,日期,广告客户,垂直,creative_size,位置等,以及一些指标,例如投放的展示次数,点击次数和收入。 该表用于显示广告效果,因此通常按一两个维度进行分组并按维度进行过滤。 我将所有内容
3回复

MySql WHERE查询速度

我听起来可能很愚蠢,但是如果我指定多个WHERE子句,它会加快mysql查询的速度还是减慢它的速度? 哪一个会更快? 范例1: 范例2:
3回复

如何使用String和DateTime列约束构造MySQL查询

我的桌子 我想在以下条件下从上表中获取数据; 我不希望任何项目都没有开始和通过。 谁能帮我。
3回复

为什么这个简单的MySQL查询如此之慢?

所以这是一个非常简单的表'tbl': 它的索引: 我正在尝试这个简单的选择: 结果:86208行(0.08秒) 但是当我想稍微修改它时: 结果是:86208行(47.30秒) 我有一个关于coumn的索引,指向的地方,我正在修改的是结果行表示。 为什
1回复

MySQL-在许多条件下的查询性能

假设有一个看起来像这样的表: 名称| 日期| value1 | value2 | value3 | ... | value100 varchar | 日期| 浮动| 浮动| 浮动| 浮动... 我可以使用它执行SELECT语句,并使用WHERE value1&g