2010-08-18 81 views
10

我只是想知道什么是更快的SQL(特别是SQL Server)。检查日期是否为空(NULL)或比较1/0是否更快?

我可以有日期类型的一个空的列和比较,为NULL,我也可以具有非空的日期列和一个单独的bit列,bit柱比较1/0

bit列的比较会更快吗?

+0

我经常想知道这 – TimS 2010-08-18 08:07:26

回答

12

为了检查列IS NULL SQL Server实际上只是检查一下。每行都有一个NULL BITMAP存储,指示每列是否包含NULL。

+1

会查询索引的位列在datetime上比null快吗? – Omu 2011-09-30 08:56:14

+2

@ChuckNorris - 只要实际使用索引,查询索引就会更快,因为SQL Server可以直接寻找感兴趣的行。如果'datetime'列本身被编入索引,这也是真的。 – 2011-09-30 08:59:54

1

该位将更快,因为加载到内存的位将只加载1个字节,加载日期将需要8个字节。比较本身将花费同一时间,但从磁盘加载需要更多时间。除非你使用一台非常旧的服务器或者需要加载多于10^8的行,否则你不会注意到任何事情。

+0

SQL Server将只加载整个8KB页面进出内存。 – 2010-08-18 11:49:58

2

所有其他的事情都是平等的,我会说比特会更快,因为它是一个“小”的数据类型。但是,如果性能在这里非常重要(并且我认为这是由于该问题),那么您应该始终进行测试,因为可能存在其他因素,如索引,影响此的缓存等。

这听起来像你正在试图决定一个字段的数据类型,它将记录事件X是否发生。因此,无论是时间戳(发生X时)或只是一个位(如果X发生,则为1,否则为0)。在这种情况下,我会试着去找日期,因为它会给你提供更多的信息(不仅是X是否发生,而且还有确切的发生时间),这对未来报告的目的最有可能是有用的。如果微小的性能增益真的更重要,只有反对这一点。

2

简短的回答,如果你只有1和0,像位图索引1,0是超级快。空值不在某些sqlengines上编入索引,所以'null'和'not null'很慢。但是,在抛弃这个之前,先考虑实体语义。如果你知道我的意思,那么最好有一个语义表定义。

速度来自在这种情况下使用索引而不是数据大小的能力。

编辑
请参阅Martin Smith的回答。这对于s​​qlserver更有意义,我被Oracle DB带走了,我的错误在这里。

+2

问题是关于SQL服务器。除非您选择设置筛选索引以忽略它们,否则SQL Server中的空值会被编入索引。空值在存储中也用NULL BITMAP表示,所以我不确定会有什么区别。 – 2010-08-18 11:52:12

9

我只是做了一个简单的测试:

DECLARE @d DATETIME 
     ,@b BIT = 0 

SELECT 1 
WHERE @d IS NULL 

SELECT 2 
WHERE @b = 0 

实际执行计划结果表明计算作为相对于该批次完全相同成本。

Actual Execution Plan

也许有人可以撕裂这一点,但对我来说,似乎没有任何区别。


多个测试

SET DATEFORMAT ymd; 

CREATE TABLE #datenulltest 
(
    dteDate datetime NULL 
) 

CREATE TABLE #datebittest 
(
    dteDate datetime NOT NULL, 
    bitNull bit DEFAULT (1) 
) 

INSERT INTO #datenulltest (dteDate) 
SELECT CASE WHEN CONVERT(bit, number % 2) = 1 THEN '2010-08-18' ELSE NULL END 
FROM master..spt_values 

INSERT INTO #datebittest (dteDate, bitNull) 
SELECT '2010-08-18', CASE WHEN CONVERT(bit, number % 2) = 1 THEN 0 ELSE 1 END 
FROM master..spt_values 


SELECT 1 
FROM #datenulltest 
WHERE dteDate IS NULL 

SELECT 2 
FROM #datebittest 
WHERE bitNull = CONVERT(bit, 1) 


DROP TABLE #datenulltest 
DROP TABLE #datebittest 

Actual Execution Plan

dteDate IS NULL结果:

IS NULL tooltip

bitNull = 1结果:

bitNull = 1

OK,所以这个扩展的测试出现再次与相同的响应。
我们可以整天这样做 - 这需要一些非常复杂的查询来找出平均速度更快的查询。

+0

查询优化程序根据几种策略确定要使用的执行计划。动态采样就是其中之一。如果它确定直接表访问(全表扫描)提取比基于索引的提取有效,则使用它。如果数据量很小,这是非常正确的,但如果数据量很大,则统计数据会有所不同。 – questzen 2010-08-18 09:56:30

+0

@questzen定义巨大的 – Omu 2010-08-18 10:17:51

+1

这是一个难以衡量的问题,但如果我们考虑到两个场景都会从同一个表中获取过滤器的数据,那么大多数计算都会以相同的方式执行。我也可以测试这个,忍受着我。 – Codesleuth 2010-08-18 10:20:01