2011-12-16 4 views
2
SELECT * FROM tableName WHERE (ISNULL(columnName,0) > 0) 

ИЛИWHERE (ISNULL (ColumnName, 0)> 0) против WHERE (ColumnName IS NOT NULL) И (ColumnName> 0)

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

какой лучше?

ColumnName имеет int тип данных

+0

Почему бы вам не воспользоваться SQL Query Analyzer? – Gnat

+3

Вы должны понимать, что значение NULL по сравнению с 0 никогда не вернет True, поэтому вам не нужно его проверять. Вы также должны знать, что, если Оптимизатор достаточно умен, чтобы исправить это для вас, ISNULL (columnName, 0)> 0 не сможет воспользоваться индексом в вашем столбце. Таким образом, это будет преимуществом второй формы, если вам нужно сравнение с NULL (чего у вас нет). – GilM

+0

Я считаю, что @GilM имеет лучший ответ. Удостовериться, что ваши запросы используют индексы (sargeable), могут быть довольно важными. – Fionnuala

ответ

7

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

SELECT * FROM tableName WHERE columnName > 0 
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; 
+3

-1 ерунда. Избегание выражений, не поддающихся определению, не относится к преждевременной оптимизации. –

+0

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

+1

Согласитесь с Мартином Смитом. Сопротивление - это просто лучшая практика. Вы учитываете только время выполнения. Я использовал эту технику, чтобы получить 1000-кратное улучшение в избранных запросах, написанных кем-то, не понимающим концепцию. – Anon246

3

А почему бы и нет WHERE columnName > 0? Остальное условие кажется излишним: Nulls не будут возвращены.

+0

Позднее на 25 секунд потеряно 15 очков. Извини :( – IsmailS

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