Как работает предложение where в MySQL?

0

У меня есть сомнения. Предположим, что R и S - 2 отношения с атрибутами A и B соответственно. Если у меня есть запрос

Select * 
From R, S
Where R.A = S.B 

Это работает как double For Loop в c или С++

For( i=0; i<n; i++)
    For( j=0; j<n; j++)
        if (i == j)
           //DO some work 
  • 4
    Это отражает определенное непонимание того , что SQL является. Смысл SQL заключается в том, что вы описываете природу желаемых результатов, а базовый механизм SQL разрабатывает план запросов, который наиболее эффективно создает этот набор результатов. То, как выглядит этот план, зависит от статистики и индексов, которые могут меняться при каждом выполнении запроса. Краткая версия: «Нет, если ваши таблицы правильно проиндексированы».
Теги:

5 ответов

2
Лучший ответ

Прежде всего: неизвестно, как mysql будет внутренне оптимизировать запрос (не зная внутренних элементов mysql).

В чистых реляционных базах данных это то, что вы делаете:

SELECT * FROM R, S → выполнить перекрестное соединение, которое генерирует все (r, s) кортежи.

WHERE R.A = S.B → теперь выберите те кортежи, которые имеют это поведение

Таким образом, он будет обрабатывать все кортежи (более или менее похожий на ваш код). Тем не менее, вполне возможно, что mysql внутренне уменьшит это до более эффективного внутреннего соединения, которое никогда не создает все кортежи, но только кортежи, где R.A=S.B действителен.

  • 0
    Я должен надеяться, что есть способ узнать, как MySQL оптимизирует запрос. Это детерминистично, не так ли? Так что кто-то, знающий о внутренностях MySQL, должен быть в состоянии описать, что делает MySQL. И это с открытым исходным кодом, верно? Любой, кто достаточно предан, должен иметь возможность изучить программу и узнать, что делает MySQL.
  • 0
    Хорошо, да, если вы знаете реализацию, вы можете знать это :).
Показать ещё 1 комментарий
2

Если индексов ни одного из этих атрибутов нет, то это именно то, что MySQL должен будет сделать, и это может быть очень неэффективно.

Однако индексы делают все различия в мире. Например, если есть индекс на S.B, то MySQL может сделать что-то более похожее:

for (i=0; i<n_r; i++) { // loop over all rows in R
    matching_rows = retrieve_from_index_s_b(i); // very fast operation, like direct array access
    for (j=0; j<matching_rows.length(); j++)
        // do some work 
}

Аналогично, если индекс находится на R.A вместо этого, тогда внешний цикл будет находиться в строках в S, а внутренний цикл будет только соответствовать строки в R.

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

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

  • 0
    +1 за настройку своего примера, чтобы показать влияние использования индексов.
2

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

1

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

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

1

То, что вы описываете, является стратегией объединения nested loops. Оптимизатор может выбрать эту или другую стратегию соединения (доступные опции будут зависеть от СУРБД вот резюме некоторых общих алгоритмов объединения).

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню