Предотвращение вложенных запросов

Насколько Важный это для предотвращения вложенных запросов.

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

Так они действительно настолько плохо. Есть ли способ использовать вложенные запросы без временных таблиц и filesort

18
задан hobodave 6 May 2010 в 06:11
поделиться

2 ответа

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

Мне известны следующие факторы:

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

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

Я бы даже сказал, что это очень полезная практика.

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

РЕДАКТИРОВАТЬ: Процедурное против реляционного
Мышление в терминах операций над множеством и процедурного сводится к эквивалентности в некоторых выражениях алгебры множеств, например, выбор в объединении эквивалентен объединению выборок. Между ними нет разницы.
Но когда вы сравниваете две процедуры, например, применяете критерии выбора к каждому элементу объединения с помощью создания объединения и затем применения выбора, это две совершенно разные процедуры, которые могут иметь очень разные свойства. (например, использование ЦП, ввода-вывода, памяти).

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

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

Следовательно, не нужно думать как, только что.

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

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

(Примечание: выше обсуждаются теоретические основы, важные для проектирования базы данных; на практике вышеупомянутые концепции отклоняются - не все эквивалентные перезаписи запроса обязательно выполняются так быстро, кластеризованные первичные ключи действительно заставляют таблицы иметь порядок наследования на диске и т. Д. ... но эти отклонения являются всего лишь отклонениями; тот факт, что не все эквивалентные запросы выполняются так быстро, является несовершенством самой СУБД, а не концепций, лежащих в основе нее)

8
ответ дан 30 November 2019 в 09:35
поделиться

Я не уверен, как это выглядит в MySQL 5.1 или 5.5, но в 5.0.x вложенные запросы обычно имеют ужасную производительность, потому что MySQL выполняет подзапросы для каждая строка, полученная из основного запроса. Это, вероятно, не относится к более зрелым базам данных, таким как MsSQL, которые внутренне могут переписывать вложенные запросы в соединения, но я никогда не использовал MsSQL, поэтому я не знаю наверняка .

http://dev.mysql.com/doc/refman/5.0/en/rewriting-subqueries.html

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

Подзапросы и объединения

1
ответ дан 30 November 2019 в 09:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: