Динамическая оптимизация запросов - PullRequest
6 голосов
/ 12 января 2012

У меня есть задание для бизнеса, которое в основном сводится к извлечению данных из базы данных (Microsoft SQL Server 2008). В ходе этого процесса пользователи смогут выбирать, какие столбцы выбрать, какое представление выбирать, и создавать предложение WHERE. На основе того, что выбирает пользователь, запрос SQL строится соответственно. Требование состоит в том, что пользователь может выбрать ЛЮБОЙ столбец в ЛЮБОМ представлении и отфильтровать по ЛЮБОМУ столбцу в предложении WHERE. Компания не хочет, чтобы решение использовало хранилище данных / OLAP, и хочет ограничить любое стороннее программное обеспечение. Поэтому в основном им просто нужно приложение .NET Windows Forms, которое динамически создает запросы SQL на основе графического интерфейса и подключается к базе данных.

Меня интересует, как оптимизировать запросы. Я ни в коем случае не хорош в оптимизации запросов SQL, но моя первая мысль была: что если пользователь выберет фильтрацию по столбцу, у которого нет индекса (в предложении WHERE)? Предоставляя пользователю такую ​​гибкость, он потенциально может создавать запросы, которые настолько неэффективны, что для их выполнения потребуется много времени.

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

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

Есть предложения?

Заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 13 января 2012

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

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

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

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

Для ваших запросов вам необходимо их параметризовать, но вам не нужно кэшировать их во всех случаях.Если ваши запросы, как правило, требуют больших затрат (поэтому время компиляции несущественно), вы захотите запускать их с OPTION RECOMPILE, чтобы SQL Server мог адаптироваться к точным значениям времени выполнения всех параметров.

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

Регулярно запускайте sp_updatestats.

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

1 голос
/ 12 января 2012

Во-первых, для улучшения способности SQL Server оптимизировать, кэшировать и компилировать запросы / операторы

  • Убедитесь, что пользовательский интерфейс поддерживает IN и BETWEEN, позволяя пользователям создавать свои собственные предложения WHERE.
  • Сортируйте условия И или ИЛИ так, чтобы индексированные столбцы были первыми, а затем в алфавитном порядке остальных столбцов.
    • Если вы разрешаете использовать вложенные AND и OR в предложении WHERE, это можетбыть более трудным
  • Использовать * параметризованные запросы "
WHERE C1 = 'foo' AND C3 = 'bar' AND C2 = 42
-- if C3 is an indexed column then 
WHERE C3 = @parm1 AND C1 = @parm2 AND C2 = @parm3

Во-вторых, для расширения возможностей пользователей

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

РЕДАКТИРОВАТЬ ИЛИ -> ИЛИ ИЛИ в отношении Мартина СмКомментарий, это называется коротким замыканием.

Рассмотрим логику

A = True OR B = True OR C = True

Если A действительно True, нет необходимости оценивать B или C, чтобы условие было истинным

A = True AND B = True AND C = True

В этом случае, если A ложно, нет необходимости оценивать B или C, чтобы условие было ложным.

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