Результаты функции кэширования в SQL Server 2000 - PullRequest
6 голосов
/ 11 марта 2009

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

Однако, похоже, что SQL Server 2000 имеет глупое произвольное правило о том, что функции являются «детерминированными». Вставки, обновления и регулярные вызовы хранимых процедур запрещены. Однако расширенные хранимые процедуры разрешены. Как это детерминировано? Если другой сеанс изменяет состояние базы данных, выходные данные функции все равно изменятся.

Я схожу с ума. Я думал, что смогу сделать кеширование прозрачным для пользователя. Это возможно? У меня нет разрешения на развертывание расширенных хранимых процедур.

EDIT:

Это ограничение действует до 2008 года. Ради Бога, вы не можете называть RAND!

Кеш будет реализован мной в БД. Кеш - это любое хранилище данных, используемое для кеширования ...

EDIT:

Нет случаев, когда одни и те же аргументы функции будут давать разные результаты, за исключением изменений в базовых данных. Это платформа BI, и единственные изменения происходят от запланированного ETL, когда я бы TRUNCATE кеш-таблицы.

Это интенсивные вычисления временных рядов ввода / вывода, порядка O (n ^ 4). У меня нет мандата на изменение базовой таблицы или индексов. Кроме того, многие из этих функций используют одни и те же промежуточные функции, и кэширование позволяет их использовать.

UDF не являются действительно детерминированными, если они не учитывают изменения в состоянии базы данных. В чем смысл? SQL Server кеширует? (Ирония.) Если SQL Server кэширует, то он должен истекать при изменениях таблиц, связанных схемой. Если они связаны схемой, то почему бы не связать таблицы, которые модифицирует функция? Я могу понять, почему процы не разрешены, хотя это просто небрежно; просто схема связывает процы. И, кстати, зачем разрешать расширенные хранимые процедуры? Вы не можете отследить, что они делают, чтобы обеспечить детерминизм !!! Argh !!!

EDIT:

Мой вопрос: есть ли способ лениво кэшировать результаты функции таким образом, чтобы их можно было использовать в представлении?

1 Ответ

2 голосов
/ 11 марта 2009

Детерминированный означает, что одни и те же входные данные возвращают одинаковые выходные данные независимо от времени и базы данных.

SQL Server (любая версия) не кэширует UDF - я считаю, что он не вызовет UDF дважды в одной строке, но это так.

Я использовал один трюк (кажется, я разместил его здесь на SO):

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

Вызвать UDF через набор строк DISTINCT и кэшировать результаты во временную таблицу. Если вы вызываете UDF только с 100 000 наборов параметров из 17 000 000 наборов строк, это очень гораздо более эффективно.

Присоединение к временной таблице (в основном преобразование из логики на основе кода в логику на основе таблицы) для получения значений.

Эта таблица может быть использована по мере необходимости или даже сохранена.

Добавление в таблицу может быть выполнено первым СЛЕДУЮЩИМ СОЕДИНЕНИЕМ, чтобы найти отсутствующие кэшированные записи.

Это работает как для однорядных табличных UDF, так и для скалярных UDF. Я в основном использую его для табличных UDF. В SQL Server 2005 есть исправление, которое должно учитывать производительность UDF - я жду, когда администраторы базы данных протестируют его перед развертыванием в рабочей среде.

...