Альтернативный способ сравнения двух столбцов в таблице с точки зрения производительности в SQL Server

#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 в a VARCHAR , что действительно снижает производительность. Затраты на конвертацию и сравнение также намного медленнее. Что-то подобное ISNULL(Column1, -1) <> ISNULL(Column2, -1) вы могли бы использовать, поскольку оно сохраняет INT значения, но предполагает это Column1 и Column2 никогда не содержит отрицательных значений.