В каком порядке MySQL JOIN оценены?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

26
задан Matt O'Brien 7 March 2016 в 23:29
поделиться

7 ответов

  1. ИСПОЛЬЗУЯ (имя поля) краткий способ сказать ОТНОСИТЕЛЬНО table1.fieldname = table2.fieldname.

  2. SQL не определяет 'порядок', в котором сделаны СОЕДИНЕНИЯ, потому что это не природа языка. Очевидно, порядок должен быть определен в операторе, но ВНУТРЕННЕЕ ОБЪЕДИНЕНИЕ можно считать коммутативным: можно перечислить их в любом порядке, и Вы получите те же результаты.

    Однако при построении ВЫБОРА... СОЕДИНЕНИЕ, особенно то, которое включает ЛЕВЫЕ СОЕДИНЕНИЯ, я нашел, что имеет смысл рассматривать третье СОЕДИНЕНИЕ как соединение новой таблицы к результатам первого СОЕДИНЕНИЯ, четвертое СОЕДИНЕНИЕ как присоединение к результатам второго СОЕДИНЕНИЯ, и так далее.

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

  3. номер путем запрос собран, это требует, чтобы у компаний и пользователей и был companyid, задания имеет идентификатор пользователя и jobid, и useraccounts имеет идентификатор пользователя. Однако только одной из компаний или пользователь нужен идентификатор пользователя для СОЕДИНЕНИЯ для работы.

  4. оператор Where фильтрует целый результат - т.е. все столбцы, к которым ПРИСОЕДИНЯЮТСЯ - использование столбца, предоставленного таблицей заданий.

26
ответ дан staticsan 28 November 2019 в 07:27
поделиться

Я не могу ответить немного о синтаксисе USING. Это странно. Я никогда раньше этого не видел, вместо этого всегда использовал предложение ON.

Но я могу сказать , что порядок операций JOIN определяется динамически оптимизатором запросов, когда он строит свой план запросов на основе системы эвристики оптимизации, некоторые из которых:

  1. Выполняется ли JOIN в поле первичного ключа? Если это так, это получает высокий приоритет в плане запроса.

  2. Выполняется ли JOIN в поле внешнего ключа? Это также получает высокий приоритет.

  3. Существует ли индекс в объединенном поле? Если это так, увеличьте приоритет.

  4. Выполняется ли операция JOIN над полем в предложении WHERE? Можно ли оценить выражение предложения WHERE, изучив индекс (а не выполнив сканирование таблицы)? Это главная возможность оптимизации, поэтому она получает значительный приоритет.

  5. Какова мощность объединенного столбца? Столбцы с большим количеством элементов дают оптимизатору больше возможностей для распознавания ложных совпадений (тех, которые не удовлетворяют условию WHERE или предложению ON), поэтому объединения с большим количеством элементов обычно обрабатываются до объединений с низким числом элементов.

  6. Сколько фактических строк в объединенной таблице? Объединение с таблицей, содержащей только 100 значений, приведет к меньшему взрыву данных, чем объединение с таблицей с десятью миллионами строк.

Во всяком случае ... дело в том ... что есть много переменных, которые входят в план выполнения запроса. Если вы хотите увидеть, как MySQL оптимизирует свои запросы, используйте синтаксис EXPLAIN.

И вот хорошая статья для чтения:

http://www.informit.com/articles/article.aspx?p=377652


НА РЕДАКТИРОВАНИИ:

Чтобы ответить на ваш 4-й вопрос: вы не запрашиваете таблицу компаний. Вы запрашиваете объединенный перекрестный продукт ВСЕХ четырех таблиц в своих предложениях FROM и USING.

Псевдоним j.jobid - это просто полное имя одного из столбцов в этой объединенной коллекции таблиц.

11
ответ дан benjismith 28 November 2019 в 07:27
поделиться

СМ. http://dev.mysql.com/doc/refman/5.0/en/join.html

И начните читать здесь:

<час>

Присоединяются к Изменениям Обработки в Начале MySQL 5.0.12

с MySQL 5.0.12, естественные соединения и соединения с ИСПОЛЬЗОВАНИЕМ, включая варианты внешнего объединения, обрабатываются согласно стандарту SQL:2003. Цель состояла в том, чтобы выровнять синтаксис и семантику MySQL относительно ЕСТЕСТВЕННОГО СОЕДИНЕНИЯ и СОЕДИНЕНИЯ... ИСПОЛЬЗУЯ Согласно SQL:2003. Однако эти изменения в обработке соединения могут привести к различным выходным столбцам для некоторых соединений. Кроме того, некоторые запросы, которые, казалось, работали правильно в более старых версиях, должны быть переписаны для исполнения стандарта.

Эти изменения имеют пять основных аспектов:

  • способ, которым MySQL определяет столбцы результата ЕСТЕСТВЕННЫХ или ИСПОЛЬЗУЯ операции соединения (и таким образом результат всего ИЗ пункта).

  • Расширение ВЫБОРА * и ВЫБОРА tbl_name.* в список выбранных столбцов.

  • Разрешение имен столбцов в ЕСТЕСТВЕННОМ или ИСПОЛЬЗУЯ соединения.

  • Преобразование ЕСТЕСТВЕННЫХ или ИСПОЛЬЗУЯ соединения в СОЕДИНЕНИЕ... НА.

  • Разрешение имен столбцов в При условии СОЕДИНЕНИЯ... НА.

0
ответ дан micahwittman 28 November 2019 в 07:27
поделиться

Я не уверен насчет части ON vs USING (хотя этот сайт говорит, что они одинаковы)

Что касается вопроса заказа, то он полностью зависит от реализации (и, вероятно, запроса). MYSQL, скорее всего, выбирает ордер при компиляции запроса. Если вы хотите навязать конкретный порядок, вам нужно будет «вложить» ваши запросы:

SELECT c.*
FROM companies AS c 
    JOIN (SELECT * FROM users AS u 
        JOIN (SELECT * FROM  jobs AS j USING(userid) 
              JOIN useraccounts AS us USING(userid) 
              WHERE j.jobid = 123)
    )

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

0
ответ дан luke 28 November 2019 в 07:27
поделиться

1) Используя не точно то же как на, но это - стенография, где обе таблицы имеют столбец с тем же именем, Вы присоединяетесь на... см.: http://www.java2s.com/Tutorial/MySQL/0100__Table-Join/ThekeywordUSINGcanbeusedasareplacementfortheONkeywordduringthetableJoins.htm

более трудно читать, по-моему, таким образом, я пошел бы обстоятельно объясняющий соединения.

3) Это не ясно из этого запроса, но я предположил бы, что это не делает.

2) Принятие Вы присоединяетесь через другие таблицы (не все непосредственно на companyies), порядок в этом запросе действительно имеет значение... посмотрите сравнения ниже:

Origional:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u USING(companyid) 
    JOIN jobs AS j USING(userid) 
    JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

, Что я думаю, что это, вероятно, предлагает:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u on u.companyid = c.companyid
    JOIN jobs AS j on j.userid = u.userid
    JOIN useraccounts AS us on us.userid = u.userid 
WHERE j.jobid = 123

Вы могли переключить Вас строки, присоединяющиеся к заданиям & usersaccounts здесь.

, На что было бы похоже, присоединилось ли все на компании:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u on u.companyid = c.companyid
    JOIN jobs AS j on j.userid = c.userid
    JOIN useraccounts AS us on us.userid = c.userid
WHERE j.jobid = 123

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

4.) Волшебство sql состоит в том, что можно только показать определенные столбцы, но все они - их для сортировки и фильтрации...

, если Вы возвратились

SELECT c.*, j.jobid....  

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

0
ответ дан Dave K 28 November 2019 в 07:27
поделиться

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

Схема сборки:

CREATE TABLE users (
  name text
);

CREATE TABLE orders (
  order_id text,
  user_name text
);

CREATE TABLE shipments (
  order_id text,
  fulfiller text
);

Добавить данные:

INSERT INTO users VALUES ('Bob'), ('Mary');

INSERT INTO orders VALUES ('order1', 'Bob');

INSERT INTO shipments VALUES ('order1', 'Fulfilling Mary');

Выполнить запрос:

SELECT *
  FROM users
       LEFT OUTER JOIN orders
       ON orders.user_name = users.name
       JOIN shipments
       ON shipments.order_id = orders.order_id

Результат:

Только Боб строка возвращается

Анализ:

В этом запросе сначала было оценено LEFT OUTER JOIN, а JOIN - по составному результату LEFT OUTER JOIN.

Второй запрос:

SELECT *
  FROM users
       LEFT OUTER JOIN (
         orders
         JOIN shipments
         ON shipments.order_id = orders.order_id)
         ON orders.user_name = users.name

Результат:

Одна строка для Боба (с данными исполнения) и одна строка для Мэри с NULL для данных исполнения.

Анализ:

Скобки изменили порядок оценки.


Дополнительную документацию по MySQL можно найти по адресу https://dev.mysql.com/doc/refman/5.5/en/nested-join-optimization.html

0
ответ дан William Entriken 28 November 2019 в 07:27
поделиться

В MySQL часто интересно спросить оптимизатор запросов, что он планирует делать, с помощью:

EXPLAIN SELECT [...]

См. «7.2.1 Оптимизация запросов с помощью EXPLAIN»

3
ответ дан NickZoic 28 November 2019 в 07:27
поделиться
Другие вопросы по тегам:

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