Результат кэширования оператора SELECT для повторного использования в нескольких запросах - PullRequest
4 голосов
/ 19 января 2012

У меня достаточно сложный запрос для извлечения поля Id интересующих меня результатов на основе параметров, введенных пользователем.

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

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

База данных находится в MS SQL Server, и я использую .NET 3.5.

Ответы [ 8 ]

1 голос
/ 26 марта 2012

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

http://msdn.microsoft.com/en-us/library/bb510489.aspx

1 голос
/ 22 марта 2012

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

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

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

Наиболее интуитивный подходдля «кэширования» набор идентификаторов в базе данных представляет собой временную таблицу (если она названа #something, она является частной для соединения и поэтому может использоваться параллельными независимыми клиентами; или она может называться ##something и быть глобальной).Если в таблице будет много записей, необходимы индексы.Для достижения оптимальной производительности индекс должен быть кластеризованным (допускается только один для каждой таблицы) или создаваться только после создания этого набора, где создание индекса выполняется немного быстрее.

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

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

Независимо от выбранного вами подхода не угадывайте характеристики производительности и поведение оптимизатора запросов.Научитесь отображать планы выполнения запросов (в SQL Server Management Studio) и убедитесь, что вы видите доступ к индексу, а не вложенные циклы, объединяющие несколько больших наборов данных;добавляйте только те индексы, которые наглядно и радикально изменят производительность ваших запросов.Правильно выбранный индекс часто может изменить производительность запроса в 1000 раз, поэтому его довольно сложно изучить, но важно для успеха.

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

1 голос
/ 20 марта 2012

Если вы планируете кешировать результирующий набор в коде своего приложения, то ASP.NET имеет кеш, в вашей Winform будет объект, содержащий данные, с которыми вы можете повторно использовать эти данные.

Если вы планируете сделать то же самое в SQL Server, вы можете рассмотреть возможность использования индексированных представлений для определения идентификаторов. Представление будет реализовано, и, следовательно, вы сможете быстрее получить результаты. Вы можете даже рассмотреть возможность использования промежуточного стола для временного хранения идентификатора.

0 голосов
/ 26 марта 2012

Вы можете создать Global temporary Table.Создайте таблицу на лету.Теперь вставьте записи согласно вашему запросу.Получите доступ к этой таблице в вашем следующем запросе в ваших объединениях ... для повторного использования

0 голосов
/ 20 марта 2012

Как часто меняются данные, которые вы будете запрашивать?Для меня это звучит как идеальный сценарий для хранилищ данных, где вы объединяете данные для более быстрого извлечения данных и создаете таблицы точно так, как ваш DTO хочет видеть данные.Этот метод отличается от индексированного представления тем, что это просто таблица, в которой будут выполняться операции быстрого поиска, и его можно особенно улучшить, если правильно настроить индексы для столбцов, для которых планируется запросить

0 голосов
/ 19 января 2012

Вы можете использовать Memcached для кэширования значений в памяти. Как я вижу, есть некоторые .net порты.

0 голосов
/ 19 января 2012

Лучший подход зависит от того, как часто меняется Id или как часто вы хотите посмотреть его снова.

Один из методов - просто сохранить результат в кеше объектов ASP.NET, используя объект Cache (также доступный из HttpRuntime.Cache). Например (со страницы):

this.Cache["key"] = "value";

Существует множество возможных вариантов этой темы.

0 голосов
/ 19 января 2012

Для SQL Server корпорация Майкрософт обычно рекомендует использовать хранимые процедуры, когда это целесообразно.

Вот несколько преимуществ:

http://blog.sqlauthority.com/2007/04/13/sql-server-stored-procedures-advantages-and-best-advantage/

* Execution plan retention and reuse
* Query auto-parameterization
* Encapsulation of business rules and policies
* Application modularization
* Sharing of application logic between applications
* Access to database objects that is both secure and uniform
* Consistent, safe data modification
* Network bandwidth conservation
* Support for automatic execution at system start-up
* Enhanced hardware and software capabilities
* Improved security
* Reduced development cost and increased reliability
* Centralized security, administration, and maintenance for common routines

Стоит также отметить, что в отличие от других поставщиков РСУБД (например, Oracle), MSSQL автоматически кэширует все планы выполнения:

http://msdn.microsoft.com/en-us/library/ms973918.aspx

Однако для последних двух версий SQL Server выполнение планы кэшируются для всех пакетов T-SQL, независимо от того, они находятся в хранимой процедуре

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