这是一个相当温和的问题,但是
我有一个相当大的存储过程,我正在尝试简化可读性
它包含许多union子句,其语句如下图1所示。
图1
SELECT COUNT(1) AS Total
FROM Orders
WHERE (NOT EXISTS (
SELECT 1
FROM (
SELECT Id
FROM OrderLineItems
WHERE Orders.Id = Order_Id) AS Sub
WHERE EXISTS (
SELECT 1
FROM NormalizedLineItems
WHERE (Sub.Id = OrderLineItem_Id)
AND (OutOfStock = 1))))
AND (EXISTS (
SELECT 1 AS Total
FROM OrderShipments
WHERE (Orders.Id = Order_Id)
AND (CarrierApproved = 0)))
AND (IsQuote = 0)
AND (Cancelled = 0)
AND (Archived = 0)
AND (Completed = 0)
AND (Holding = 0)
然而,每个陈述中都有许多重复出现的模式
以下模式多次出现图2
图2
WHERE (NOT EXISTS (
SELECT 1
FROM (
SELECT Id
FROM OrderLineItems
WHERE Orders.Id = Order_Id) AS Sub
WHERE EXISTS (
SELECT 1
FROM NormalizedLineItems
WHERE (Sub.Id = OrderLineItem_Id)
AND (OutOfStock = 1))))
我试图(出于可读性目的)减少主存储过程中的代码
所以我认为对于UDF的id性能测试,我想出了下面的图3
图3
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION TestFunction (@OrderId int)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
SELECT 1 AS Total
FROM (
SELECT OrderLineItems.Id AS Id
FROM OrderLineItems
WHERE @OrderId = Order_Id) AS Sub
WHERE EXISTS (
SELECT 1 AS Total
FROM NormalizedLineItems
WHERE (Sub.Id = OrderLineItem_Id)
AND (OutOfStock = 1)))
GO
虽然以上所有编译,但我不确定我是否在正确的轨道上,我在尝试将上述UDF应用于原始查询时遇到各种各样的问题
我想知道是否有人可以给我一个具体的例子,说明如何将图1中的Fig.2抽象为UDF,这样我至少可以对解决方案进行性能测试,看看它是否值得
注意:我确实知道用户定义的功能可能是一场性能噩梦,但即使在我可以测试的阶段也不行
由于
答案 0 :(得分:1)
创建一个只包含一个名为order_id
的列的order_ids表Insert into order_ids
select order_id from
FROM Orders
WHERE (NOT EXISTS (
SELECT 1
FROM (
SELECT Id
FROM OrderLineItems
WHERE Orders.Id = Order_Id) AS Sub
WHERE EXISTS (
SELECT 1
FROM NormalizedLineItems
WHERE (Sub.Id = OrderLineItem_Id)
AND (OutOfStock = 1))))
然后你可以像这样简化你的Sql:
SELECT COUNT(1) AS Total
FROM Orders
join order_ids
on order_ids.order_id = Orders.order_id
...
如果您的重复陈述仅在一个查询中, Common Table Expression是最佳选择:
with CTE_order_ids as
(select order_id from
FROM Orders
WHERE (NOT EXISTS (
SELECT 1
FROM (
SELECT Id
FROM OrderLineItems
WHERE Orders.Id = Order_Id) AS Sub
WHERE EXISTS (
SELECT 1
FROM NormalizedLineItems
WHERE (Sub.Id = OrderLineItem_Id)
AND (OutOfStock = 1))))
)
SELECT COUNT(1) AS Total
FROM Orders
join CTE_order_ids
on order_ids.order_id = Orders.order_id
...