Быстрее проверить, что дата (не) NULL или сравнить бит с 1/0?

Мне просто интересно, что быстрее в SQL (в частности, SQL Server).

Я мог бы иметь столбец с нулевым значением типа Date и сравнить его с NULL, или я мог бы иметь столбец Date с нулевым значением и отдельный столбец bit и сравнить столбец bit с 1/0.

Будет ли сравнение с столбцом bit быстрее?

Ответ 1

Чтобы проверить, что столбец IS NULL SQL Server фактически будет просто проверять бит в любом случае. Существует NULL BITMAP для каждой строки, указывающей, содержит ли каждый столбец NULL или нет.

Ответ 2

Я просто сделал простой тест для этого:

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

ОК, поэтому этот расширенный тест снова появляется с теми же ответами.
Мы могли бы сделать это весь день - для выяснения того, что быстрее в среднем, потребуется очень сложный запрос.

Ответ 3

При прочих равных условиях я бы сказал, что бит будет быстрее, потому что это "меньший" тип данных. Однако, если производительность здесь очень важна (и я предполагаю, что это из-за вопроса), вы должны всегда тестировать, так как могут быть другие факторы, такие как индексы, кэширование, которые влияют на это.

Похоже, вы пытаетесь определить тип данных для поля, который будет записывать, произошло ли событие X или нет. Итак, либо временная метка (когда X произошла), либо просто бит (1, если произошло X, иначе 0). В этом случае у меня возникнет соблазн пойти на Дату, так как она даст вам больше информации (не только о том, произошло ли X, но и когда именно), что, скорее всего, будет полезно в будущем для целей отчетности. Только идти против этого, если незначительное повышение производительности действительно более важно.

Ответ 4

Короткий ответ. Если у вас есть только 1 и 0, то что-то вроде индекса бит-карты 1,0 является быстрым. Нули не индексируются на определенных sqlengines, поэтому "null" и "not null" являются медленными. Тем не менее, подумайте о семантике сущности, прежде чем это выйдет. Всегда лучше иметь определение семантической таблицы, если вы знаете, что я имею в виду.

В этом случае скорость зависит от возможности использования индексов, а не от размера данных.

Edit
См. Ответ Мартина Смита. Это имеет смысл для sqlserver, я увлекся оракулом DB, моя ошибка здесь.

Ответ 5

Бит будет быстрее, так как загрузка бит в память будет загружать только 1 байт, а загрузка даты займет 8 байтов. Само по себе сравнение займет одно и то же время, но загрузка с диска займет больше времени. Если вы не используете очень старый сервер или вам нужно загрузить более 10 ^ 8 строк, вы ничего не заметите.