Mysql 这个查询看起来优化了吗?
我正在为一个应用程序编写一个查询,该应用程序需要列出所有产品的购买次数 我想出了这个,它的工作,但我不太确定它是如何优化。由于我大量使用ORM,我的SQL真的生锈了,但在这种情况下,查询是一种更优雅的解决方案 你能发现这个查询有什么错误吗Mysql 这个查询看起来优化了吗?,mysql,sql,optimization,Mysql,Sql,Optimization,我正在为一个应用程序编写一个查询,该应用程序需要列出所有产品的购买次数 我想出了这个,它的工作,但我不太确定它是如何优化。由于我大量使用ORM,我的SQL真的生锈了,但在这种情况下,查询是一种更优雅的解决方案 你能发现这个查询有什么错误吗 架构(包含相关字段)如下所示: *orders* id, paid *orderitems* order_id, product_id *products* id 使现代化 这是MySQL的它给了你正确的答案吗 除了修改它以去掉内部查询
架构(包含相关字段)如下所示:
*orders* id, paid
*orderitems* order_id, product_id
*products* id
使现代化
这是MySQL的它给了你正确的答案吗
除了修改它以去掉内部查询中的SELECT之外,我看不出它有什么问题。它给了您正确的答案吗 除了修改它以除去内部查询中的SELECT之外,我看不出它有任何问题。您有“左外部联接”,这可能是一个性能问题,具体取决于您的数据库。 上次我记得它在MySQL上造成了灾难,而它在SQLite中并不存在。我认为Oracle可以很好地处理它,我想DB和MSSQL也是如此 编辑:如果我没记错的话,左外连接在MySQL上可能会慢几个数量级,但是如果我在这里过时了,请纠正我:)您有“左外连接”,这可能是一个性能问题,具体取决于您的数据库。 上次我记得它在MySQL上造成了灾难,而它在SQLite中并不存在。我认为Oracle可以很好地处理它,我想DB和MSSQL也是如此
编辑:如果我没记错的话,左外连接在MySQL上可能会慢几个数量级,但是如果我在这里过时了,请纠正我:)未测试的代码,但是尝试一下:
SELECT products.id,
MIN(products.long_name) AS name,
count(oi.order_id) AS sold
FROM (products
LEFT OUTER JOIN orderitemss AS oi ON oi.product_id = products.id)
INNER JOIN orders AS o ON oi.order_id = o.id
WHERE orders.paid = 1
GROUP BY products.id
我不知道左外连接是否需要括号,MySQL是否允许多个连接,但是MIN(products.long_name)只给出了描述,因为对于每个products.id,您只有一个描述
也许圆括号需要位于内部联接的周围。未测试的代码,但请尝试:
SELECT products.id,
MIN(products.long_name) AS name,
count(oi.order_id) AS sold
FROM (products
LEFT OUTER JOIN orderitemss AS oi ON oi.product_id = products.id)
INNER JOIN orders AS o ON oi.order_id = o.id
WHERE orders.paid = 1
GROUP BY products.id
我不知道左外连接是否需要括号,MySQL是否允许多个连接,但是MIN(products.long_name)只给出了描述,因为对于每个products.id,您只有一个描述
也许括号需要在内部连接的周围。我不确定“(选择*”…业务)
这会执行(总是一个好的开始),我认为这相当于发布的内容
SELECT products.id,
products.long_name AS name,
count(oi.order_id) AS sold
FROM products
LEFT OUTER JOIN
orderitems AS oi
INNER JOIN
orders
ON oi.order_id = orders.id AND orders.paid = 1
ON oi.product_id = products.id
GROUP BY products.id
我不确定“(选择*”…业务
这会执行(总是一个好的开始),我认为这相当于发布的内容
SELECT products.id,
products.long_name AS name,
count(oi.order_id) AS sold
FROM products
LEFT OUTER JOIN
orderitems AS oi
INNER JOIN
orders
ON oi.order_id = orders.id AND orders.paid = 1
ON oi.product_id = products.id
GROUP BY products.id
这里为我们这些筑巢障碍者提供了一个解决方案
但是,我在MS SQL Server上测试了你的解决方案,Mike的和我的解决方案,并且查询计划是相同的。我不能说MySql,但是如果MS SQL Server是一个好的选择,你可能会发现这三个解决方案的性能都是相同的。如果是这样的话,我想你会选择哪一个解决方案对你来说是最清晰的。这里有一个解决方案供我们这些人使用o嵌套受损。(当我开始嵌套联接时,我感到非常困惑)
但是,我在MS SQL Server上测试了您的解决方案,Mike的和我的解决方案,并且查询计划是相同的。我不能说MySql,但是如果MS SQL Server是一个可以信赖的解决方案,您可能会发现这三个解决方案的性能都是相同的。如果是这样,我想您可以选择最清晰的解决方案。这是一个子查询表单
SELECT
p.id,
p.long_name AS name,
(SELECT COUNT(*) FROM OrderItems oi WHERE oi.order_id in
(SELECT o.id FROM Orders o WHERE o.Paid = 1 AND o.Product_id = p.id)
) as sold
FROM Products p
它的性能应该大致相当于连接表单。如果没有,请告诉我。这是一个子查询表单
SELECT
p.id,
p.long_name AS name,
(SELECT COUNT(*) FROM OrderItems oi WHERE oi.order_id in
(SELECT o.id FROM Orders o WHERE o.Paid = 1 AND o.Product_id = p.id)
) as sold
FROM Products p
它的性能应该大致相当于联接表单。如果没有,请告诉我。谢谢!您的查询的问题是,它似乎否定了左侧外部联接,因为结果不会返回没有销售的产品。然后括号应该围绕内部联接。谢谢!您的查询的问题是它似乎否定了左侧外部联接外部连接作为结果不会返回没有销售的产品。那么括号应该在内部连接的周围。如果内部连接周围没有括号,您确定这会给出与原始查询相同的答案吗?lassevek,它确实给出了正确的答案,我猜MySQL会正确解释它,因为它是嵌套连接。我仍然添加了括号内。因此,MySQL不反对选择products.long_名称,因为它既不是按列分组也不是聚合?令人印象深刻。@thuthΖΖtituthΖΖΥ:products.long_名称可能是products.id的函数依赖项,因此它应该给出正确的结果。如果内部联接没有括号,您确定这会给出相同的answ吗呃作为原始查询?lassevek,它确实给出了正确的答案,我想MySQL对它的解释是正确的,因为它是一个嵌套连接。尽管如此,我还是添加了括号。因此,MySQL不反对选择products.long_名称,它既不是按列分组也不是聚合?令人印象深刻。@titΖΖΖΖΥ:products.long_名称可能很有趣products.id的函数依赖性,因此它应该给出正确的结果。谢谢!我在MySQL中检查了查询计划,看起来您和Mike的查询计划是相同的,我的解决方案又多了一步。谢谢!我在MySQL中检查了查询计划,看起来您和Mike的查询计划是相同的,我的解决方案又多了一步步