Предупреждение SQL Server 2000 “НЕТ ПРЕДИКАТА СОЕДИНЕНИЯ” - почему?

StackOverflow https://stackoverflow.com/questions/290885

  •  08-07-2019
  •  | 
  •  

Вопрос

У меня странная проблема с SQL Server 2000, и я просто не могу придумать причину, по которой это могло произойти.

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

(VARCHAR(11), INT, DATETIME)   /* can't change this, so don't suggest I should */

Итак, присоединиться к ним таким образом достаточно просто:

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = 'Foo'

Глядя на план выполнения запроса, я вижу это:

  • Кластеризованный поиск по индексу [db].[dbo].[table1].[PK_table1] (48%)
  • Кластеризованный поиск по индексу [db].[dbo].[table2].[PK_table2] (51%)
  • Вложенные циклы (внутреннее соединение) (1%) Предупреждение:НЕТ ПРЕДИКАТА ОБЪЕДИНЕНИЯ
  • Выберите (0%)

Теперь, если я сделаю это (обратите внимание на строку NVARCHAR!):

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = N'Foo'

Я получаю:

  • Сканирование кластеризованного индекса [db].[dbo].[table1].[PK_table1] (98%)
  • Кластеризованный поиск по индексу [db].[dbo].[table2].[PK_table2] (1%)
  • Вложенные циклы (внутреннее соединение) (1%) здесь нет предупреждения
  • Выберите (0%)

Такое поведение оставляет меня немного озадаченным.

  • Почему появляется предупреждение "NO JOIN PREDICATE" и почему оно исчезает, когда я меняю 'Foo' Для N'Foo'?Мои ключевые столбцы не имеют типа NVARCHAR, так что это не должно иметь никакого значения, или должно?
  • Имеет ли наличие этого предупреждения негативные последствия или я могу его проигнорировать?
  • Почему он переключается с поиска по индексу на сканирование по индексу?

Некоторая справочная информация:Мощность таблицы составляет ок.25 000 записей в одной таблице, ок.12 000 записей в другом.Уровень совместимости базы данных равен 80 (SQL Server 2000) параметры сортировки по умолчанию равны SQL_Latin1_General_CP1_CI_AS, если это вообще имеет какое-то значение.

Вот содержание @@VERSION:

Microsoft SQL Server 2000 - 8.00.2273 (Intel X86) 7 марта 2008 22:19:58 Авторское право (c) 1988-2003 Microsoft Corporation Enterprise Edition на Windows NT 5.0 (сборка 2195:Пакет обновления 4)

P.S.:Я осознаю КB322854, но это, очевидно, не то.

Это было полезно?

Решение

Почему он переключается с поиска по индексу на сканирование по индексу?

Это в значительной степени предположение, но вот что:

В первом случае ('Foo') MSSQL распознает, что искомое значение идеально соответствует первой части индекса в t1, и поэтому использует индекс для поиска записи в t1 (поиск по индексу, возможно, двоичный поиск).Найдя запись в t1, индекс которой идеально соответствует t2, он может использовать индекс для поиска записей в t2.

Во втором случае (N'Foo') MSSQL распознает, что у него НЕТ идеального соответствия между индексом и запрашиваемым значением, поэтому он не может использовать индекс в качестве индекса, но должен выполнить полное сканирование таблицы.Однако, поскольку индекс содержит необходимую информацию (в другой форме) и меньше, чем полная таблица, он может выполнить полное сканирование индекса, как если бы это была таблица (это быстрее, чем сканирование таблицы, поскольку для чтения с диска требуется меньше страниц;тем не менее, похоже, что это занимает примерно в 90 раз больше времени, чем поиск по индексу)

Другие советы

Из SQLServerCentral:

запросы могут иметь то, что выглядит как идеально сформированное условие соединения.Но когда вы изучите план запроса, вы увидите предупреждение "Нет предиката объединения", указывающее на то, что 2 из задействованных таблиц не имеют предиката (при объединении).Добавление опции (принудительный порядок) к запросу приводит к созданию совершенно другого плана, и предупреждение исчезает (в некоторых случаях).Вот откуда вы знаете, что это и есть проблема.Большинство запросов, которые я видел, которые работают лучше на SQL 2000, демонстрируют эту проблему.Предполагается, что накопительное обновление 4 до SP 2 должно решить проблему.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top