WHERE(ISNULL(columnName,0)> 0)vs WHERE(columnName IS NOT NULL)AND(columnName> 0)

时间:2011-12-16 13:43:31

标签: sql-server performance tsql

SELECT * FROM tableName WHERE (ISNULL(columnName,0) > 0)

OR

SELECT * FROM tableName WHERE (columnName IS NOT NULL) AND (columnName > 0)

哪一个更好?

columnName具有int数据类型

3 个答案:

答案 0 :(得分:7)

您不需要在查询中检查空值,所以我猜这会更好。

SELECT * FROM tableName WHERE columnName > 0

答案 1 :(得分:3)

为什么不只是WHERE columnName > 0?其余的条件似乎是多余的:不会返回空值。

答案 2 :(得分:0)

更好的方法?

我认为后者更具可读性,其他人可能不同意。你可能有一种有利于前者的家居风格,在这种情况下毫无疑问。

至于性能,我非常怀疑要么是导致性能问题所以你不应该优化,过早的优化是所有邪恶的根源。


这是一个很好的问题,问When is optimisation premature?,而here是该术语的定义。

在这种情况下,性能大致按此顺序改进:

SELECT Count(*) FROM BigTable WHERE (ISNULL(SmallNumber,0) > 0) --140 ms
SELECT Count(*) FROM BigTable WHERE (SmallNumber IS NOT NULL) AND (SmallNumber > 0) --41 ms
SELECT Count(*) FROM BigTable WHERE SmallNumber > 0 --30 ms

但是将Count(*)*交换,并且任何微小的性能提升都会在海中丢失,以便检索行。

使用这个丑陋的代码块来创建一个大表后,你可以自己测试它。

CREATE TABLE [dbo].[BigTable]( [ID] [int] IDENTITY(1,1) NOT NULL, [BigNumber] [bigint] NULL, [SmallNumber] [int] NULL,
    CONSTRAINT [PK_BigTable] PRIMARY KEY CLUSTERED ( [ID] ASC ));
CREATE NONCLUSTERED INDEX [IX_BigTable] ON [dbo].[BigTable] ([SmallNumber] ASC);
With Digits as ( SELECT 0 AS d UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 
    UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9),
OneToAMillion as (SELECT (100000 * D6.d) + (10000 * D5.d) + (1000 * D4.d) + (100 * D3.d) + (10 * D2.d) + (1 * D1.d) AS Number
    FROM Digits D6, Digits D5, Digits D4, Digits D3, Digits D2, Digits D1)
INSERT INTO dbo.BigTable (BigNumber, SmallNumber) SELECT CAST(CHECKSUM(NEWID()) as BigInt) * CHECKSUM(NEWID()), CHECKSUM(NEWID()) FROM OneToAMillion;
UPDATE BigTable SET SmallNumber = Null WHERE BigNumber < 0;