我有我的SQL查询的问题:
表价格数百万行,必须正确查询。一切运行良好,并且页面花费了约400ms的加载时间,直到我对数据库进行了更新(使用Prod数据库中的新数据库对其进行了更新),并且一切都中断了。现在加载页面需要120秒。
它的运行就好在我们的督促和预督促环境,但在我的dev的包膜超慢。我正在使用相同的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个不同的行为(prod和dev)? 通常如何处理大表上的左联接?
谢谢
答案 0 :(得分:1)
在“键”列的p1_行上查看prod和dev解释查询: 在开发中为NULL 在产品中是search_idx。
结论:如果在prod和dev环境中运行“ bin / console d:s:u --dump-sql”,则需要在dB模式中找到一些差异。
答案 1 :(得分:1)
可能有很多原因。您会在开发服务器上看到快速的结果,因为记录较少,而实时服务器包含大量记录(请参阅explait语句中的rows
列)。
我建议检查所有键和您的join
列类型。与“ on
”子句结合使用的每一列都应具有相似的类型,否则将会减慢速度。因此,请确保列为int+unsigned
或varchar
等。
在输出中查找possible_key, key and extra
列,并尝试从以下链接中了解,这将帮助您找到合适的解决方案
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html
另请参见上面链接中的“解释输出解释”部分。