PostgreSQL函数/查询无限执行

时间:2015-01-23 18:16:18

标签: sql postgresql function infinite

所以我尝试使用我在查询中创建的函数,当我执行查询时它会永远运行。 该功能找到客户,他的订单最大 其中的产品数量。 该查询将其与任何其他查询一起返回 订购了相同数量产品的客户。

这是功能:

CREATE OR REPLACE FUNCTION max_orderQty ()
RETURNS bigint
AS $$
     SELECT SUM(OrderQty)
     FROM Customer,SalesOrderHeader,SalesOrderDetail
     WHERE Customer.CustomerID = SalesOrderHeader.CustomerID
     AND SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
     GROUP BY SalesOrderHeader.CustomerID
     ORDER BY SUM(OrderQty) DESC LIMIT 1;
$$ LANGUAGE SQL;  

以下是查询:

SELECT SUM(OrderQty),SalesOrderHeader.CustomerID
FROM Customer,SalesOrderHeader,SalesOrderDetail
WHERE Customer.CustomerID = SalesOrderHeader.CustomerID
AND SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
GROUP BY SalesOrderHeader.CustomerID
HAVING SUM(OrderQty) = max_orderQty();

这也有效,它解决了同样的问题:(在220ms内)

SELECT SUM(OrderQty),SalesOrderHeader.CustomerID
FROM Customer,SalesOrderHeader,SalesOrderDetail
WHERE Customer.CustomerID = SalesOrderHeader.CustomerID
AND SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
GROUP BY SalesOrderHeader.CustomerID
HAVING SUM(OrderQty) = (SELECT SUM(OrderQty)
                        FROM Customer,SalesOrderHeader,SalesOrderDetail
                        WHERE Customer.CustomerID = SalesOrderHeader.CustomerID
                        AND SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
                        GROUP BY SalesOrderHeader.CustomerID
                        ORDER BY SUM(OrderQty) DESC LIMIT 1);

因此,当我尝试将其拆分为函数/查询时,它只会永远运行而且我 找不到原因。我想用一个函数代替 更快。那是错的吗?

非常感谢任何帮助。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

没有理由认为函数会更快。您的问题是正在为输出中的每一行调用该函数 - 并且每次都要重新计算。

您应该能够通过将函数声明为STABLE来解决此问题。默认值为VOLATILE

您可以在documentation中了解这些细微差别。

编辑:

只需调用一次函数,就可以强制它运行得更快:

SELECT SUM(OrderQty),SalesOrderHeader.CustomerID
FROM Customer JOIN
     SalesOrderHeader
     ON Customer.CustomerID = SalesOrderHeader.CustomerID JOIN
     SalesOrderDetail
     ON SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID CROSS JOIN
     (SELECT max_orderQty() as maxoq) x
GROUP BY SalesOrderHeader.CustomerID
HAVING SUM(OrderQty) = MAX(maxoq);