#sql #sql-server #tsql
Вопрос:
У меня есть приведенный ниже запрос и получение правильного результата. Но я хочу знать, какой запрос является стандартным с точки зрения производительности/кода из приведенных ниже запросов.
DECLARE @TBL AS TABLE (Column1 INT NULL ,Column2 INT NULL)
INSERT INTO @TBL(Column1,Column2)
VALUES(25,25)
,(21,NULL)
Запрос 1:
SELECT * FROM @TBL
WHERE COALESCE(Column1,'') <> COALESCE(Column2,'')
OR(Column1 IS NULL AND Column2 IS NOT NULL)
Запрос 2:
SELECT * FROM @TBL
WHERE ISNULL(NULLIF(Column1, Column2), NULLIF(Column2, Column1)) IS NOT NULL
OR(Column1 IS NULL AND Column2 IS NOT NULL)
Запрос 3:
SELECT * FROM @TBL WHERE ISNULL(Column1,'') ! = ISNULL(Column2,'')
OR(Column1 IS NULL AND Column2 IS NOT NULL)
Результат должен быть
Column1 Colum2
21 Null
Может ли кто-нибудь, пожалуйста, предложить для вышесказанного.
Комментарии:
1. Ни один из них, этот, вероятно, лучше
WHERE NOT EXISTS (SELECT Column1 INTERSECT SELECT Column2)
. Хотя неясно, чего вы здесь хотите , похоже, что ваш синтаксис будет''
равенNULL
, было ли это намерением?2. Выполнение этого сравнения между двумя столбцами во время выполнения потребует полного сканирования обоих столбцов во всех строках, независимо от того, как вы их пишете. Чтобы оптимизировать производительность этого
SELECT
, вы можете поместить проверку выражения на равенство в вычисляемый столбец и проиндексировать его, если эта проверка выполняется достаточно часто, чтобы гарантировать, что3. @SasiBhushanaRao . . . Ваш стол действительно слишком мал, чтобы беспокоиться о соображениях производительности. Все запросы должны быть настолько быстрыми, что будет трудно измерить различия, если вы не запустите их тысячи раз для сравнения времени.
4. Я бы предположил, что это должен был быть Минимальный , воспроизводимый пример
5. @MartinSmith Если вы посмотрите на статью dupe и Пола Уайта, связанную там, вы увидите, что этот синтаксис не требует полного сканирования и будет использовать поиск по индексу. Кстати,
...<>...OR...IS NULL OR...IS NULL
он также компилируется до поиска по индексу.
Ответ №1:
Я не совсем уверен, чего вы хотите достичь, и поэтому принял следующий вопрос за мой ответ:
Return every row where Column1 is not equal to Column2 independently whether they are null or not.
Этот вопрос я бы решил так, избегая любых функций, которые, как я предполагаю, должны быть медленнее.
SELECT * FROM @TBL
WHERE (Column1 <> Column2) OR
((Column1 IS NULL) AND (Column2 IS NOT NULL)) OR
((Column2 IS NULL) AND (Column1 IS NOT NULL));
Окончательный ответ вы узнаете, проведя измерения в вашей среде.
Комментарии:
1. Этот результат хорош для меня. Но я сомневаюсь, чем приведенный ниже запрос отличается от запроса, который вы предложили ВЫБРАТЬ * ИЗ @TBL, ГДЕ ОБЪЕДИНЯЕТСЯ(столбец 1,») < > ОБЪЕДИНЯЕТСЯ(столбец 2,») ИЛИ(Столбец 1 РАВЕН НУЛЮ, А столбец 2 НЕ РАВЕН НУЛЮ) Я имею в виду производительность или стандарт, что хорошо, не могли бы вы предложить
2. В своих запросах вы преобразуете каждое значение из an
INT
в aVARCHAR
, что действительно снижает производительность. Затраты на конвертацию и сравнение также намного медленнее. Что-то подобноеISNULL(Column1, -1) <> ISNULL(Column2, -1)
вы могли бы использовать, поскольку оно сохраняетINT
значения, но предполагает этоColumn1
иColumn2
никогда не содержит отрицательных значений.