Каковы ваши наиболее распространенные оптимизации SQL? - PullRequest
30 голосов
/ 26 августа 2009

Какая у вас самая распространенная оптимизация SQL, которую вы использовали?

Ответы [ 17 ]

33 голосов
/ 26 августа 2009

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

Добавление индексов. Это делается не так часто, так как для некоторых таблиц не требуется индекс, отличный от индекса, созданного для первичного ключа.

30 голосов
/ 26 августа 2009

Мой любимый список советов (подробно объясняется здесь) выглядит следующим образом

  1. Попробуйте ограничить набор результатов запросов с помощью предложения WHERE.
  2. Попробуйте ограничить набор результатов запросов, возвращая только определенные столбцы из таблицы, а не все столбцы таблицы.
  3. Использование представлений и хранимых процедур вместо сложных запросов.
  4. По возможности старайтесь избегать использования курсоров SQL Server.
  5. Если вам нужно вернуть общее количество строк в таблице, вы можете использовать альтернативный способ вместо оператора SELECT COUNT (*).
  6. Старайтесь по возможности использовать ограничения вместо триггеров.
  7. Использование табличных переменных вместо временных таблиц.
  8. Старайтесь по возможности избегать предложения HAVING.
  9. По возможности старайтесь избегать использования предложения DISTINCT.
  10. Включите оператор SET NOCOUNT ON в ваши хранимые процедуры, чтобы остановить сообщение, указывающее количество строк, затронутых оператором T-SQL.
  11. Используйте операторы select с ключевым словом TOP или оператор SET ROWCOUNT, если вам нужно вернуть только первые n строк.
  12. Используйте подсказку таблицы FAST number_rows, если вам нужно быстро вернуть строки 'number_rows'.
  13. Старайтесь по возможности использовать оператор UNION ALL вместо UNION.
  14. Не используйте подсказки оптимизатора в своих запросах.
8 голосов
/ 26 августа 2009

Безусловно: создание индексов покрытия

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

Но также стоит упомянуть:

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

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

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

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

Конечно, я мог бы идти весь день ...

Rob

6 голосов
/ 26 августа 2009

Кэширование выходных данных. Избегать давления на базу данных представляется разумной оптимизацией.

+ 1 memcached.

3 голосов
/ 26 августа 2009

Индекс внешних ключей!

Может быть, это не оптимизация синтаксиса SQL-запросов, а скорее оптимизация хранилища. Но я вижу, что это повторяется все время и это любимая мозоль.

2 голосов
/ 26 августа 2009

Лучшая оптимизация, которую я когда-либо проводил с использованием SQL, заключалась в том, чтобы по-настоящему понять, что необходимо для обработки данных и УДАЛИТЬ тонны SQL из запроса.

Самый быстрый запрос - это запрос, который не нужно запускать.

ДЕЙСТВИТЕЛЬНО ДУМАЙТЕ о том, что вы делаете с данными. Вы работаете построчно? (затем используйте набор на основе кода).

  • Вам действительно нужно присоединиться ко всем этим столам?

  • Могут ли два небольших (простых) запроса выполнять работу лучше и быстрее, чем один большой запрос?

  • Если объединить эти два запроса в один запрос, может ли он работать быстрее?

Наконец, ПРОФИЛЬ ваших запросов (ОБЪЯСНИТЕ ПЛАН или SQL PROFILER) и посмотрите на "IO gets". Как правило, вы хотите уменьшить число GET до отношения, равного 10, для каждой строки вывода.

2 голосов
/ 26 августа 2009

1) Мне еще предстоит найти ситуацию, когда

SELECT Field1, Field2, (SELECT Count(*) FROM tblLinked WHERE tblLinked.Field3 = tblSource.Field3) AS TheTotal
FROM tblSource

не улучшается при левом присоединении к производной таблице.

SELECT Field1, Field2, IsNull(Linked.TheTotal,0) AS TheTotal
FROM tblSource
LEFT JOIN (SELECT Field3, Count(*) AS TheTotal
    FROM tblLinked
    GROUP BY Field3) AS Linked ON tblSource.Field3 = Linked.Field3

2) Не сортируйте результаты на сервере, если приложение-потребитель не может сделать это самостоятельно. Это реже применяется к веб-приложениям, но для настольных приложений клиентский ПК обычно имеет достаточно мощности и может с радостью выполнить какую-то задачу.

3) Используйте EXISTS вместо проверки количества соответствующих записей.

4) Не зацикливайтесь на выполнении запроса только в одном предложении SELECT. Разумное использование табличных переменных (а иногда и временных таблиц) может значительно сократить количество обрабатываемых строк.

1 голос
/ 26 августа 2009

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

  • Не считайте общее количество предметов.
  • Показывать только "n" число первых элементов (например, только первые 100).

Такими методами пользуется Google, Twitter и другие сайты. В поиске Google нет точного количества результатов. Есть только приблизительное число. Twitter не позволяет пользователю просматривать все прошлые твиты. Он показывает только последний номер n (я не могу вспомнить, сколько).

Существует некоторая ссылка из блога производительности MySQL .

1 голос
/ 26 августа 2009

Самые большие оптимизации, которые я использовал в последнее время, довольно просты.

Сохраняйте как можно большую часть бизнес-логики как можно ближе к серверу sql. Ака хранит ваш бизнес-код на той же машине, что и сервер sql. Пусть ваша бизнес-логика возвращает как можно меньше кода обратно конечному клиенту.

Сделайте ваш SQL-запрос как можно более коротким, как сказал Фрост, используйте одиночные операторы обновления над несколькими.

Используйте транзакции только тогда, когда они вам нужны

Создание временных таблиц для частичных объединений для ускорения объединений (не забудьте их проиндексировать)

1 голос
/ 26 августа 2009

Две самые важные вещи в моем опыте - это меньше соединений и меньше запросов. Кроме тех, что есть много специфичных для БД вещей, COUNT (*) относительно медленен в PgSQL, подвыборы медленны в MySQL и т. Д.

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