Другой план выполнения для похожих запросов - PullRequest
1 голос
/ 08 июня 2010

Я выполняю два очень похожих запроса на обновление, но по неизвестной мне причине они используют совершенно разные планы выполнения.Обычно это не было бы проблемой, но они оба обновляют одинаковое количество строк, но один использует план выполнения, который значительно уступает другому, 4 секунды против 2 минут, при увеличении это вызывает огромную проблему.

Единственное различие между двумя запросами состоит в том, что один использует столбец CLI, а другой - DLI.Эти столбцы имеют абсолютно одинаковый тип данных, и оба они проиндексированы в точности одинаково, но для плана выполнения запроса DLI индекс не используется.

Любая помощь по поводу того, почему это происходит, приветствуется.

-- Query 1
UPDATE a
 SET DestKey = ( 
 SELECT TOP 1 b.PrefixKey 
 FROM refPrefixDetail AS b 
 WHERE a.DLI LIKE b.Prefix + '%' 
 ORDER BY len(b.Prefix) DESC )
FROM CallData AS a

-- Query 2
UPDATE a
 SET DestKey = ( 
 SELECT TOP 1 b.PrefixKey 
 FROM refPrefixDetail b 
 WHERE a.CLI LIKE b.Prefix + '%' 
 ORDER BY len(b.Prefix) DESC )
FROM CallData AS a

Ответы [ 2 ]

3 голосов
/ 08 июня 2010

Изучите статистику по этим двум столбцам таблицы (как значения данных для столбцов распределяются по всем строкам). Это, вероятно, объяснит разницу ... Один из этих столбцов может иметь распределение значений, которое может привести к тому, что при обработке запроса потребуется исследовать значительно большее количество строк, чем требовалось бы для другого запроса (число или обновленные строки контролируются первой запоминаемой частью), возможно, оптимизатор запросов решит не использовать индекс ... Обновление статистики сделает их более точными, но если распределение значений таково, что оптимизатор выберет не использовать индекс, тогда вам может не повезти ...

Здесь полезно понять, как работают индексы. Индекс - это древовидная структура узлов, где каждый узел (начиная с корневого узла) содержит информацию, которая позволяет обработчику запросов определить, к какой ветви дерева перейти к следующей, на основе значения, которое оно «ищет». Это аналог бинарного дерева, за исключением того, что в базах данных деревья не являются бинарными, на каждом уровне может быть более 2 ветвей ниже каждого узла.

Таким образом, для индекса, для прохождения индекса от корневого уровня до конечного уровня требуется, чтобы процессор считывал индекс один раз для каждого уровня в индексе hiearchy. (например, если индекс имеет глубину 5 уровней, он должен выполнить 5 операций ввода-вывода для каждой записи, которую он ищет.

Так, в этом примере, скажем, если запрос должен проверить более чем приблизительно 20% записей в таблице (в зависимости от распределения значений столбца, по которому выполняется поиск), тогда оптимизатор запросов скажет: Само по себе «self, чтобы найти 20% записей с пятью вводами-выводами на каждый поиск записей, равно количеству операций ввода-вывода, что и при чтении всей таблицы», поэтому он просто игнорирует индекс и выполняет Таблица сканирования.

На самом деле нет никакого способа избежать этого, кроме как путем добавления дополнительных критериев к вашему запросу, чтобы еще больше ограничить число записей, которые запрос должен изучить, чтобы сгенерировать его результаты ....

1 голос
/ 08 июня 2010

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

...