首页 > 解决方案 > 如何处理大表上的左连接?有意想不到的行为

问题描述

我的 SQL 查询有问题:

表价格数百万行,必须正确查询。一切运行良好,页面加载大约需要 400 毫秒,直到我对数据库进行了更新(使用我们的 Prod DB 中的新数据库对其进行了更新)并且它破坏了一切。现在加载页面需要 120 秒。

它在我们的 prod 和 pre prod 环境中运行得很好,但在我的开发环境中非常慢。我正在使用相同的 mysql 版本和 php 版本运行。将 Symfony 4 与学说 2 ORM 一起使用。

我正在处理的查询如下:

SELECT 
c0_.id AS id_0, 
c0_.ticker AS ticker_1, 
c0_.name AS name_2, 
p1_.id AS id_3, 
p1_.rank AS rank_4, 
p1_.price_usd AS price_usd_5, 
p1_.1d_volume_usd AS 1d_volume_usd_6, 
p1_.change_1h AS change_1h_7, 
p1_.change_1d AS change_1d_8, 
p1_.change_7d AS change_7d_9, 
c2_.id AS id_10, 
c2_.market_cap AS market_cap_11, 
s3_.id AS id_12, 
s3_.score_buzz AS score_buzz_13, 
s3_.score_average AS score_average_14 
FROM coins c0_ 
LEFT JOIN prices p1_ ON c0_.id = p1_.ticker_id 
AND (p1_.last_updated >= ?) LEFT JOIN cmc c2_ ON c0_.id = c2_.ticker_id 
AND (c2_.last_updated >= ?) LEFT JOIN scores s3_ ON c0_.id = s3_.ticker_id 
AND (s3_.to_datetime >= ?) 
WHERE c0_.is_active = 1 ORDER BY c0_.rank_cmc ASC, p1_.last_updated DESC, c2_.last_updated DESC, s3_.to_datetime DESC

问题来自那部分:

LEFT JOIN prices p1_ ON c0_.id = p1_.ticker_id AND (p1_.last_updated >= ?)

如果我删除这部分,它工作得很好。铅从哪里来?为什么我对同一个查询有 2 种不同的行为(产品和开发)?您通常如何处理大表上的左连接?

谢谢

编辑:这是 DEV 中查询的解释: 在此处输入图像描述

以下是 PROD 中查询的说明: 在此处输入图像描述

EDIT2:价格开发指数: 在此处输入图像描述

标签: phpmysqlsqlsymfony

解决方案


查看 prod 和 dev 解释查询,在 p1_ 行的“key”列: 在 dev 中它是 NULL 在 prod 中它是 search_idx。

结论:如果您在 prod 和 dev 环境中运行“bin/console d:s:u --dump-sql”,则需要在 dB 模式中找到一些差异。


推荐阅读