Следует ли использовать временные таблицы для передачи данных между хранимыми процедурами? - PullRequest
1 голос
/ 12 ноября 2009

У меня есть несколько функций поиска (хранимых процедур), которые должны возвращать результаты с одинаковыми столбцами.

Это подход, который был принят:

Каждая хранимая процедура имела общую структуру:

CREATE TABLE #searchTmp (CustomerID uniqueIdentifier)</p> <pre><code>INSERT INTO #searchTmp SELECT C.CustomerID FROM /**** do actual search here, based on stored proc arguments ****/ EXEC spSearchResults DROP TABLE #searchTmp

В приведенном выше примере spSearchResults использует таблицу #searchTmp для выбора. spSearchResults всегда возвращал таблицу с одинаковыми столбцами и имел довольно много объединений.

Однако вместо использования временной таблицы более приемлем следующий подход:

SELECT col1, col2, col3, col4, .... etc, lots of columns ... FROM table1 LEFT JOIN table 2 ON ... etc, lots of joins ... WHERE ... DO ACTUAL SEARCH HERE ...

Если необходимо выполнить 10 различных поисков (например, поиск покупателя по почтовому индексу, один поиск по фамилии и т. Д.), Этот второй подход означает, что задано много дубликатов столбцов и объединений. Если код, использующий функции поиска, изменяется так, что требуется возвращать новый столбец, то есть 10 хранимых процедур, которые необходимо обновить.

Я все за первый метод, но мне просто интересно, какие преимущества дает второй метод. Спектакль?

Или есть третий способ?

Ответы [ 3 ]

1 голос
/ 12 ноября 2009

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

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

РЕДАКТИРОВАТЬ: Как говорит Марк, может быть разница в производительности из-за возможности оптимизатора запросов использовать несколько потоков в подходе с одним запросом, но не в подходе с временной таблицей. Вы должны сопоставить этот потенциальный выигрыш с огромным улучшением ремонтопригодности метода временных таблиц и решить, что для вас важнее. Как обычно в вопросах с базой данных, лучше измерить производительность, чем угадывать ее.

0 голосов
/ 12 ноября 2009

Если вы используете Microsoft Sql Server, я предпочитаю третий метод:

Create Function GetSearchKeys([Search parameters here])
Returns @Keys Table (pk Int Primary Key Not Null)
As
Begin
      Insert @Keys(pk)
      Select C.CustomerID 
      From /**** do actual search here, based 
               on Search parameters ****/
      Return
End

  -- ----------------------------------------------------

И затем, в каждом сохраненном процессе,

  SELECT col1, col2, col3, col4, .... etc, lots of columns ... 
  FROM table1 
     LEFT JOIN table 2 
        ON ... etc, lots of joins
     Join schema.GetSearchKeys([Search parameters here]) K
        on K.pk = [whatever table.column has the primary key in  it]
0 голосов
/ 12 ноября 2009

Второй должен работать лучше. Это будет меньшая доля данных, которые вы хотите вернуть.

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

Чтобы проверить это, запустите Showplan (Sybase или SQL Server) или EXPLAIN (Iracle) и т. Д., Чтобы увидеть фактический сгенерированный запрос.

...