有一种情况是我在使用IF @SKU IS NULL OR @SKU = '',但我的朋友说与IF ISNULL(@SKU, '') = ''相比,它需要更多的时间。所以你应该使用IF ISNULL(@SKU, '') = ''。但我认为我使用的是正确的。所以请建议我哪一个跑得更快。
这是我的存储过程:
CREATE PROCEDURE USP_GetExistingRefunds
(
@OrderNo VARCHAR(50),
@SKU VARCHAR(255),
@ProfileID INT
)
AS
BEGIN
--IF ISNULL(@SKU, '') = '' --this work faster or
IF @SKU IS NULL OR @SKU = '' --this work faster
BEGIN
SELECT OrderNo, SKU, ISNULL(Quantity, 0) Quantity, ISNULL(Amount, 0) Amount
FROM StoreRefundOrder SRO
INNER JOIN StoreRefundOrderItem SROI ON SRO.ID = SROI.RefundOrderID
WHERE SRO.OrderNo = @OrderNo
AND ProfileID = @ProfileID
END
ELSE
BEGIN
SELECT OrderNo, SKU, ISNULL(SUM(Quantity), 0) Quantity, ISNULL(SUM(Amount), 0) Amount
FROM StoreRefundOrder SRO
INNER JOIN StoreRefundOrderItem SROI ON SRO.ID = SROI.RefundOrderID
WHERE SRO.OrderNo = @OrderNo
AND SROI.SKU = @SKU
AND ProfileID = @ProfileID
GROUP BY OrderNo, SKU
END
END发布于 2020-02-14 00:55:26
IF/ELSE过程批处理上下文中的
这不会有任何不同。字面上需要0.00MS来确定一个值是否为空或未知,它需要0.00ms来确定是否为ISNULL(@SKU, '') = ''。如果存在差异,则很可能会以纳秒为单位进行度量。同样,这在过程化批处理的上下文中也是如此,因为语句只被计算一次。
过滤器上下文中的(例如ON、WHERE或HAVING子句)
这里的差异实际上是巨大的,它不能被低估。由于涉及到参数和变量,这很难解释,因此,为简洁起见,我使用此示例数据向您展示了一个示例:
IF OBJECT_ID('tempdb..#things','U') IS NOT NULL DROP TABLE #things;
SELECT TOP (10000) Txt = SUBSTRING(LEFT(NEWID(),36),1,ABS(CHECKSUM(NEWID())%x.N))
INTO #things
FROM (VALUES(1),(30),(40),(NULL)) AS x(N)
CROSS JOIN sys. all_columns;
UPDATE #things SET Txt = NEWID() WHERE txt = '0';
CREATE NONCLUSTERED INDEX nc_things1 ON #things(Txt);以下查询将查找包含或不包含空格或空值的行
-- Finding things that are blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE t.Txt IS NULL OR t.Txt = '';
-- Finding things that are NOT blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE NOT(t.Txt IS NULL OR t.Txt = '');
SELECT t.Txt
FROM #things AS t
WHERE t.Txt > '';
-- Finding things that are blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE ISNULL(t.Txt,'') = '';
-- Finding things that are NOT blank or NULL
SELECT t.Txt
FROM #things AS t
WHERE ISNULL(t.Txt,'') <> '';前三个查询是SARGable查询,后两个查询不是因为ISNULL。尽管有一个索引可以帮助我,但ISNULL在这里使它变得无用。这是让某人在电话簿中查找每个名字以"A“开头的人和找到每个名字以"A”结尾的人之间的区别。
SARGable谓词允许查询查找索引的一部分,其中非SARGable谓词强制查询扫描整个表,而不管存在多少匹配行(如果有)。当您处理连接到许多其他表的数百万/数十亿行时,不同之处在于一个查询在几秒钟内运行,而在某些情况下,一个查询可能运行几个小时甚至几个星期(我见过几个)。
执行计划:

请注意,最后一个WHERE t.Txt > ''也会起作用。任何非空文本值都是> '',如果t.Txt为空,则它的计算结果也将为false。我之所以包含这个,是因为这个表达式适用于过滤后的索引。唯一的问题是不能在隐式转换可以将其转换为数字0或更小的文本字段上使用它。请注意以下查询:
IF '' = 0 PRINT 'True' ELSE PRINT 'False'; -- Returns True
IF '' = '0' PRINT 'True' ELSE PRINT 'False'; -- Returns False
IF '' > -1 PRINT 'True' ELSE PRINT 'False'; -- Returns True
IF '' > '-1' PRINT 'True' ELSE PRINT 'False'; -- Returns False发布于 2020-02-13 14:35:40
IF @SKU IS NULL OR @SKU =''同时检查null和空白。在第二种情况if Isnull(@sku,'')中,您将检查null并为NULL值分配'‘。两者都是不同的情况。
发布于 2020-02-13 16:00:19
(ISNULL(@SKU, '') = '')和(@SKU IS NULL OR @SKU = '')哪个更快?
在这种情况下这真的无关紧要。如果是与列进行比较,那么(SKU IS NULL OR SKU = '')会更好,因为它可以使用索引,但是与变量的单次比较的任何差异都将是微秒级的,与SELECT语句的执行时间相比就相形见绌了。
为了简化IF语句,我可能会将其反转,如下所示
IF @SKU <> '' --Not null or empty string
BEGIN
SELECT OrderNo, SKU, ISNULL(SUM(Quantity), 0) Quantity, ISNULL(SUM(Amount), 0) Amount
FROM StoreRefundOrder SRO
INNER JOIN StoreRefundOrderItem SROI ON SRO.ID = SROI.RefundOrderID
WHERE SRO.OrderNo = @OrderNo
AND SROI.SKU = @SKU
AND ProfileID = @ProfileID
GROUP BY OrderNo, SKU
END
ELSE
BEGIN
SELECT OrderNo, SKU, ISNULL(Quantity, 0) Quantity, ISNULL(Amount, 0) Amount
FROM StoreRefundOrder SRO
INNER JOIN StoreRefundOrderItem SROI ON SRO.ID = SROI.RefundOrderID
WHERE SRO.OrderNo = @OrderNo
AND ProfileID = @ProfileID
END https://stackoverflow.com/questions/60201411
复制相似问题