非常简单,以下哪种方法在WHERE子句中更适合检索记录,其中FIELD_NAME是NOT NULL,不是空
WHERE DATALENGTH(FIELD_NAME) > 0或
WHERE ISNULL(FIELD_NAME, '') <> ''更新
据我所知,第一种方法对某些类型的字段给出了虚假的结果。同意吗?
发布于 2013-05-09 15:39:06
首先,
select *
from table
where column <> ''会给出与
select *
from table
where isnull(column, '') <> ''因为条件为UNKNOWN而不是FALSE的记录仍将被过滤掉。我一般会同意第一种选择。
DATALENGTH计数尾随空格,而与''的比较则没有。您是否希望' '与''相比较取决于您。如果你这样做了,你需要DATALENGTH。如果没有,只需将其与''进行比较。
注意,对于TEXT/NTEXT类型,不支持比较,但DATALENGTH支持。
发布于 2013-05-09 15:18:23
ISNULL是最好的方法而不是DATALENGTH。
发布于 2013-05-09 15:55:00
使用AdventureWorks2008 R2数据库进行简短测试:
CREATE INDEX IN_Person_MiddleName_FirstName_LastName
ON Person.Person (MiddleName,FirstName,LastName) ;
GO
SET STATISTICS IO ON;
SET NOCOUNT ON;
GO
PRINT 'Select #1: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p;
PRINT 'Select #2: Seek (range scan)';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE p.MiddleName <> '' -- p.MiddleName <> '' implies that {p.MiddleName IS NOT NULL} condition to be true
PRINT 'Select #3: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE DATALENGTH(p.MiddleName) > 0;
PRINT 'Select #4: Full Scan';
SELECT MiddleName,FirstName,LastName, BusinessEntityID
FROM Person.Person p
WHERE ISNULL(p.MiddleName, '') <> '';结果:
Select #1: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...
Select #2: Seek (range scan)
Table 'Person'. Scan count 2, logical reads 67, ... <-- minimum logical reads
Select #3: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...
Select #4: Full Scan
Table 'Person'. Scan count 1, logical reads 105, ...执行计划:

注1:您可以看到,Select #2 (WHERE p.MiddleName <> '')提供了最好的性能,是Server使用Index Seek (范围扫描)而不是*FULL *Index Scan的唯一情况。这是因为p.MiddleName <> ''是SARG (至少在Server 2008 R2中)。
注2: DATALENGTH( NULL )给出NULL,因此DATALENGTH(FIELD_NAME) > 0条件是错误的。
注3: ISNULL()函数用于表示(SELECT子句),而不是用于编写条件。
https://stackoverflow.com/questions/16465216
复制相似问题