MySQL View 代替子查询不返回相同的结果
Posted
技术标签:
【中文标题】MySQL View 代替子查询不返回相同的结果【英文标题】:MySQL View in place of subquery does not return the same result 【发布时间】:2020-10-24 17:57:50 【问题描述】:下面的查询正在获取有关某个玩具类别的一些信息,并显示三个状况级别(例如,全新、二手、翻新)的最新销售价格。每次销售的价格几乎总是不同的。另一件事 - 销售表行 id 不一定按时间顺序排列,例如,销售 id 为 5 的玩具可能比销售 id 为 10 的玩具发生得晚)。
此查询有效,但性能不佳。它在可管理的时间内运行,通常约为 1 秒。但是,我需要再添加一个左连接来包含更多数据,这会导致查询时间膨胀到大约 9 秒,而不是 bueno。
这是有效但非执行的查询:
SELECT b.brand_name, t.toy_id, t.toy_name, t.toy_number, tt.toy_type_name, cp.catalog_product_id, s.date_sold, s.condition_id, s.sold_price FROM brands AS b
LEFT JOIN toys AS t ON t.brand_id = b.brand_id
JOIN toy_types AS tt ON t.toy_type_id = tt.toy_type_id
LEFT JOIN catalog_products AS cp ON cp.toy_id = t.toy_id
LEFT JOIN toy_category AS tc ON tc.toy_category_id = t.toy_category_id
LEFT JOIN (
SELECT date_sold, sold_price, catalog_product_id, condition_id
FROM sales
WHERE invalid = 0 AND condition_id <= 3
ORDER BY date_sold DESC
) AS s ON s.catalog_product_id = cp.catalog_product_id
WHERE tc.toy_category_id = 1
GROUP BY t.toy_id, s.condition_id
ORDER BY t.toy_id ASC, s.condition_id ASC
但就像我说的那样,它很慢。 sales 表有大约 200k 行。
我尝试将子查询创建为视图,例如,
CREATE VIEW sales_view AS
SELECT date_sold, sold_price, catalog_product_id, condition_id
FROM sales
WHERE invalid = 0 AND condition_id <= 3
ORDER BY date_sold DESC
然后用视图替换子查询,比如
SELECT b.brand_name, t.toy_id, t.toy_name, t.toy_number, tt.toy_type_name, cp.catalog_product_id, s.date_sold, s.condition_id, s.sold_price FROM brands AS b
LEFT JOIN toys AS t ON t.brand_id = b.brand_id
JOIN toy_types AS tt ON t.toy_type_id = tt.toy_type_id
LEFT JOIN catalog_products AS cp ON cp.toy_id = t.toy_id
LEFT JOIN toy_category AS tc ON tc.toy_category_id = t.toy_category_id
LEFT JOIN sales_view AS s ON s.catalog_product_id = cp.catalog_product_id
WHERE tc.toy_category_id = 1
GROUP BY t.toy_id, s.condition_id
ORDER BY t.toy_id ASC, s.condition_id ASC
很遗憾,此更改导致查询不再获取最近的销售,它返回的销售价格也不再是最近的。
为什么table view和子查询一样select返回的结果不一样?
在阅读了我能找到的几乎所有top-n-per-group
*** 问题和博客文章之后,得到一个真正有效的查询真是太棒了。但是现在我需要将查询再扩展一步,我遇到了性能问题。如果有人想回避上述问题并提供一些优化原始查询的方法,我会全力以赴!
感谢所有帮助。
【问题讨论】:
在没有任何聚合函数的情况下,GROUP BY 子句永远不合适。剩下的就是噪音。 另外,只是为了观察,您在类别表上有一个外部联接,您似乎没有从中选择任何列。这似乎完全没有意义,除非我遗漏了什么。 @Kris 。 . .您的查询格式不正确。您在子查询中有一个order by
—— you 可能认为这会做一些有用的事情(它没有)。您的select
列与group by
不一致。我建议您提出一个新的问题,其中包含示例数据、期望的结果以及您想要完成的任务的解释。
请为每个案例提供EXPLAIN
。
【参考方案1】:
子查询性能问题的解决方案是使用此处提供的答案:Groupwise maximum
我认为这种方法只能在查询单个表时使用,但实际上即使在您连接了许多其他表时也可以使用。您只需使用s.date_sold < s2.date_sold
连接条件将同一个表左连接两次,并确保 where 子句在第二个表的 id 列中查找空值。
【讨论】:
以上是关于MySQL View 代替子查询不返回相同的结果的主要内容,如果未能解决你的问题,请参考以下文章
如果子查询在 MySQL 中返回多于 1 行,如何将 JSON 放入列数据中