#sql #oracle #oracle11g
#sql #Oracle #oracle11g
Вопрос:
Имея две таблицы products
и product_types
, обе имеют следующие строки :
products
product_types
Выполнение следующего запроса :
SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id = 1;
выдает следующий результат :
Но выполнение этого запроса :
SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id = pt.product_type_id
OR p.product_type_id = 1;
выдает следующий результат :
Обычно интерпретатор SQL начинается с одной таблицы и охватывает другую, каково правило для этого? В 1-м запросе он начинался с products
таблицы и охватывал product_types
, но во 2-м запросе он начинался с product_types
таблицы и охватывал products
таблицу (как видно из порядка). Почему это не согласовано, обычно я ожидаю, что результат 2-го запроса будет примерно таким :
Почему? Выбирается ли таблица для начала случайным образом или как?
ПРИМЕЧАНИЕ: Не обращайте внимания на запросы, это может не иметь особого смысла, меня интересует только порядок результатов.
Комментарии:
1. Правило заключается в том, что порядок результатов не определен, если в вашем запросе нет
ORDER BY
для самого внешнегоSELECT
. Точка. Даже один и тот же запрос, выполняемый несколько раз, может возвращать результаты в разных порядках.
Ответ №1:
У вас полное непонимание того, как работает SQL.
Запросы SQL представляют результаты обработки данных из реляционной базы данных. Они не отражают предпринятые шаги. SQL-запрос обрабатывается в основном в три этапа:
- Запрос проанализирован.
- Проанализированный результат генерирует оптимизированный план выполнения.
- Механизм SQL выполняет результат.
Вы заявляете:
Обычно интерпретатор SQL начинается с одной таблицы и охватывает другую, каково правило для этого?
Это далеко, очень далеко от истины.
Правда в том, что таблицы SQL и результирующие наборы представляют собой неупорядоченные наборы. У них нет порядка. Возможно, вам следует повторить это 50 раз. Два результирующих набора в разных порядках — это одно и то же.
SQL действительно поддерживает ORDER BY
предложение, потому что порядок может быть важным. Вот как вы получаете результаты в указанном порядке.
Кроме того, я бы настоятельно посоветовал вам прекратить использовать запятые в FROM
предложении. Это очень архаичный способ представления объединений. Правильный способ — использовать JOIN
ключевое слово explicit с условиями в ON
предложении — то, что было частью стандарта SQL более двух десятилетий.
Ответ №2:
Выбирается ли таблица для начала случайным образом или как?
Это может показаться случайным, но это не так. Просто оптимизатор запросов волен рассматривать различные способы выполнения запроса и выбирать план выполнения, который, по его мнению, вернет ожидаемые результаты (как определено запросом) наиболее оптимальным способом.
Даже малейшее изменение в определении запроса может привести к тому, что оптимизатор сочтет другой план выполнения более эффективным. И даже при выполнении одного и того же запроса несколько раз могут быть выбраны разные планы выполнения в разное время, если, например, изменилось распределение данных в разных задействованных таблицах (и это только одна из многих возможных причин).
Тот факт, что он может выбрать любой план выполнения, оптимальный в данной ситуации, конечно, повлияет на порядок возвращаемых строк. И это вполне соответствует тому, что может сделать оптимизатор запросов, потому что вы не запрашивали явный порядок результатов, включив ORDER BY
предложение в свой запрос.Единственный способ гарантировать согласованный порядок результатов — это явно запросить этот порядок через ORDER BY
предложение. Не позволяйте никому говорить вам обратное, они лгут.