SQL Server: встроенная таблица значений UDF и встроенное представление - PullRequest
5 голосов
/ 06 октября 2009

Я работаю с системой медицинских карт, которая хранит данные в конструкции, напоминающей электронную таблицу - дата / время в заголовках столбцов, измерения (например, имя врача, резус, тип крови) в первом столбце каждой строки, и значение в пересекающейся ячейке. Отчеты, основанные на этой конструкции, часто требуют отображения 10 или более этих мер.

Для целей отчетности в наборе данных должна быть одна строка для каждого пациента, дата / время проведения измерения и столбец для каждого измерения. По сути, нужно повернуть конструкцию на 90 градусов.

В какой-то момент я фактически использовал функциональность PIVOT в SQL Server, чтобы сделать именно это. По ряду причин стало очевидно, что этот подход не будет работать. Я решил, что буду использовать встроенное представление (IV), чтобы преобразовать данные в нужный формат. Упрощенный запрос напоминает:

SELECT patient_id, 
       datetime, 
       m1.value AS physician_name, 
       m2.value AS blood_type, 
       m3.value AS rh
  FROM patient_table
INNER JOIN ( complex query here
              WHERE measure_id=1) m1...
INNER JOIN (complex query here
              WHERE measure_id=2) m2...
LEFT OUTER JOIN (complex query here
                 WHERE measure_id=3) m3...

Как видите, в некоторых случаях эти IV используются для ограничения результирующего набора данных (INNER JOIN), в других случаях они не ограничивают набор данных (LEFT OUTER JOIN). Однако часть «сложного запроса» по существу одинакова для каждой из этих мер, за исключением разницы в measure_id. Хотя этот подход работает, он приводит к довольно большим операторам SQL, ограничивает повторное использование и подвергает запрос ошибкам.

Моя мысль состояла в том, чтобы заменить «сложный запрос» и предложение WHERE на UDF Inline Table-Value. Это значительно упростит запросы, уменьшит количество ошибок и увеличит повторное использование кода. Единственный вопрос, на мой взгляд, это производительность. Приведет ли подход UDF к значительному снижению производительности? Может ли это улучшить ситуацию?

Спасибо за ваше время и внимание.

Ответы [ 4 ]

8 голосов
/ 06 октября 2009

Правильно определенный TVF не вызовет никаких проблем. Вы найдете много претензий к внутренним взрывным TVF для проблем производительности по сравнению с представлениями или временными таблицами и переменными. Обычно не понимают, что TVF ведет себя иначе, чем точка зрения. Определение представления помещается в исходный запрос, а затем оптимизатор переставляет дерево запросов так, как оно считает нужным (если только предложение NOEXPAND не используется в индексированных представлениях). TVF имеет различную семантику, и иногда, особенно при обновлении данных, это приводит к тому, что выход TVF помещается в буфер для защиты haloween . Помогает отметить функцию WITH SCHEMABINDING, см. Улучшение планов запросов с опцией SCHEMABINDING для пользовательских функций T-SQL .

Также важно понимать понятия детерминистической и точной функции. Хотя они в основном применяются к функциям скалярного значения, это может повлиять и на TVF. См. Руководство по проектированию пользовательских функций .

2 голосов
/ 06 октября 2009

Поскольку вам нужна строка SQL и у вас может не быть возможности добавить представление или UDF в систему, вы можете использовать WITH ... AS, чтобы ограничить сложный запрос одним местом (по крайней мере, для этого оператора. ).

WITH complex(patientid, datetime, measure_id, value) AS
(Select... Complex Query)
SELECT patient_id
,        datetime
,        m1.value AS physician_name
,        m2.value AS blood_type
,        m3.value AS rh  
FROM patient_table
INNER JOIN (Select ,,,, From complex WHERE measure_id=1) m1...
INNER JOIN (Select ,,,, From complex WHERE measure_id=2) m2...
LEFT OUTER JOIN (Select ,,,, From complex WHERE measure_id=3) m3...
1 голос
/ 06 октября 2009

Sql Server 2005 ответ: Вы можете уменьшить встроенное представление с помощью таблиц temp / var. Проблемы с производительностью в этих случаях - это временные вставки, которые требуются для каждого нажатия на запрос, но если наборы результатов достаточно малы, они могут помочь. Вы можете использовать первичные ключи для таблиц var и первичные ключи / индексы для временных таблиц. Кроме обычного верования, я нашел пару статей, указывающих, что обе таблицы temp / var хранятся в базе данных temp.

Функции UDF, как мы обнаружили, менее производительны, когда у вас есть многослойные udf-файлы в сложных запросах, но они будут поддерживать удобство использования. Обязательно создайте функцию правильно для различных указанных условий. Те, которые будут использоваться для внутренних объединений, и те, которые будут использоваться для левых объединений.

Итак, в общем. Мы используем UDF, но когда обнаруживаем, что производительность снижается, мы перемещаем запрос, чтобы вставить выборки UDF в таблицы temp / var и присоединиться к ним.

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

EDIT:

Если вам необходимо выполнить это для crystal и вы планируете использовать хранимые процедуры, да, вы можете выполнять инструкции sql внутри SP для таблиц temp / var.

Дайте мне знать, если вы собираетесь использовать SP. Затем Sql также кэширует sp-планы с заданными параметрами по мере необходимости.

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

1 голос
/ 06 октября 2009

У вас также есть третий вариант; традиционный ВИД (при условии, что у вас есть ключ для присоединения). Теоретически не должно быть разницы в производительности между этими тремя вариантами, потому что SQL Server должен соответствующим образом оценивать и оптимизировать планы. Реальность такова, что иногда это происходит не так, как хотелось бы.

Преимущество традиционного представления состоит в том, что вы можете сделать его индексированным представлением и предоставить SQL Server еще одно средство повышения производительности; тем не менее, вам просто нужно проверить и посмотреть.

...