2009-04-21 6 views
2

Какой SQL будет быстрее проверять, имеет ли конкретный столбец нулевое значение или нет?Подтвердить, имеет ли столбец нулевое значение

1) SELECT * FROM TABLE1 WHERE COL1 IS NULL

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

2) SELECT COUNT (COL1) FROM TABLE1 WHERE COL1 IS NULL

Читать счетчик, который возвращается, чтобы определить, есть ли какие-либо нулевые записи

Работа с Oracle10g и SQLServer2005.

ответ

4

Я не знаю, о Oracle, но для SQL Server этот параметр, вероятно, будет быстрее всего:

SELECT TOP 1 COL1 FROM TABLE1 WHERE COL1 IS NULL; 

Таким образом, СУБД имеет только прочитать одну строку, прежде чем дать вам ответ ; другие параметры должны читать все ненулевые строки. И я указал COL1 вместо *, поэтому возможно удовлетворить запрос с индексом на COL1, делая запрос быстрее.

+0

Просто, чтобы выбрать нит, базе данных все равно придется читать несколько строк. Он просто сможет остановиться, когда он наконец достигнет того, что соответствует критериям. Он все равно должен читать все, что не соответствует критериям, пока оно не дойдет до этого. Кроме того, использование EXISTS даст то же преимущество, и я считаю, что он совместим с ANSI. –

5

Опираясь на ответ kquinn, в Oracle в том, что бы

SELECT COL1 FROM TABLE1 WHERE COL1 IS NULL AND ROWNUM = 1; 

Таким образом, СУБД имеет только прочитать одну строку, прежде чем дать вам ответ;

Это утверждение вводит в заблуждение, однако. Он должен читать все строки, пока не найдет один с отсутствующим значением столбца. Затем он может остановить и вернуть эту строку.

Если такой строки нет, она будет читать всю таблицу.

так что возможно удовлетворить запрос с помощью индекса на COL1, делая запрос быстрее.

Задание только COL1 не будет иметь большого влияния, по крайней мере, на Oracle, где (обычные B-Tree) индексы не могут использоваться для поиска значений NULL.

Возможно, вы захотите выбрать большее количество столбцов (например, значение первичного ключа), если вас интересует идентификация строки позже.

+1

Hm, в PostgreSQL (мой DB выбор), индексы B-Tree (по умолчанию) * do * хранят информацию о значениях NULL и * могут * использоваться для удовлетворения условий IS NULL в запросах; Я согласен с вами в том, что включение индекса в запрос не поможет, если индексы не могут быть использованы в любом случае. Вы хотите посмотреть, как индексы SQL Server обрабатывают NULL и видят, ведет ли он себя как Postgres или Oracle. – kquinn

6

Count (ColumnName) никогда не будет считать NULL значения, количество скачет NULLS при указании имени столбца и не рассчитывать NULLS при использовании *

запустить эту

CREATE TABLE testnulls (ID INT) 
INSERT INTO testnulls VALUES (1) 
INSERT INTO testnulls VALUES (2) 
INSERT INTO testnulls VALUES (null) 

SELECT count(*) FROM testnulls WHERE ID IS NULL --1 

SELECT count(ID) FROM testnulls WHERE ID IS NULL --0 

Я хотел бы использовать существует вместо того, чтобы так это логическое управление и остановится на первой из NULL вхождение

IF EXISTS (SELECT 1 FROM testnulls WHERE ID IS NULL) 
PRINT 'YES' 
ELSE 
PRINT 'NO' 
0

Несколько решений (колонка содержит некоторые NULLs | Колонка это все значения NULL * Test Одиночная колонка | Проверка нескольких столбцов с табличными результатами)

Если вам необходимо проверить несколько столбцов, можно использовать следующее:

Column_1 Column_2 Column_3 
-------- -------- -------- 
1  2  NULL 
1  NULL  NULL 
5  6  NULL 

Первый, тест на значения NULL и сосчитать их:

select 
    sum(case when Column_1 is null then 1 else 0 end) as Column_1, 
    sum(case when Column_2 is null then 1 else 0 end) as Column_2, 
    sum(case when Column_3 is null then 1 else 0 end) as Column_3, 
from TestTable 

Учет количества NULL:

Column_1 Column_2 Column_3 
0   1   3 

Wher e результат равен 0, нет NULL.

Второй, давайте считать не-NULLs:

select 
    sum(case when Column_1 is null then 0 else 1 end) as Column_1, 
    sum(case when Column_2 is null then 0 else 1 end) as Column_2, 
    sum(case when Column_3 is null then 0 else 1 end) as Column_3, 
from TestTable 

... Но поскольку мы рассчитываем не-NULLs здесь, это может быть упрощена:

select 
    count(Column_1) as Column_1, 
    count(Column_2) as Column_2, 
    count(Column_3) as Column_3, 
from TestTable 

Либо один дает:

Column_1 Column_2 Column_3 
3   2   0 

Если результат равен 0, столбец составленный из NULL.

Наконец, если вам нужно только проверить конкретный столбец, то TOP 1 быстрее, потому что он должен остановиться при первом попадании. Вы можете дополнительно использовать COUNT (*), чтобы дать результат логического стиля:

select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a 

0 = Там нет значения NULL, 1 = Существует, по крайней мере один NULL

select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a 

0 = Они все NULL, 1 = Существует не менее одного NULL

Надеюсь, это поможет.

Смежные вопросы