SQL Server 2000 «NO JOIN PREDICATE» предупреждение - почему? - PullRequest
0 голосов
/ 14 ноября 2008

У меня странная проблема с 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'

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

  • Поиск кластерного индекса [дБ]. [Дбо]. [Таблица1]. [PK_table1] (48%)
  • Поиск кластерного индекса [дБ]. [Дбо]. [Таблица2]. [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%)
  • Поиск кластерного индекса [дБ]. [Дбо]. [Таблица2]. [PK_table2] (1%)
  • Nested Loops (Inner Join) (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 Copyright (c) 1988-2003 Microsoft Corporation Enterprise Edition для Windows NT 5.0 (сборка 2195: пакет обновления 4)

P.S .: Мне известно о KB322854 , но это не так, очевидно.

Ответы [ 2 ]

2 голосов
/ 14 ноября 2008

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

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

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

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

0 голосов
/ 14 ноября 2008

Из SqlServerCentral :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...