Является ли более эффективным использовать ON или USING или WHERE в MySQL JOIN?

0

Предположим, у меня есть таблица foo и bar, в которой оба id являются первичными.

Есть следующий запрос:

SELECT * 
FROM foo 
JOIN bar
WHERE foo.id = bar.id
AND foo.id = :id

Выполняя следующие запросы:

SELECT * 
FROM foo 
JOIN bar ON foo.id = bar.id
AND foo.id = :id

Или же:

SELECT * 
FROM foo 
JOIN bar USING (id)
AND foo.id = :id

EXPLAINS сообщает мне, что все эти запросы являются синонимами, но мне интересно, есть ли случаи краев при использовании нескольких индексов? Я не нашел явной документации по этому вопросу.

Приложение: EXPLAINS результаты.

mysql> EXPLAIN
    ->     SELECT *
    ->     FROM foo
    ->     JOIN bar
    ->     WHERE foo.id = bar.id
    -> ;
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref         | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | foo   | NULL       | index  | PRIMARY       | PRIMARY | 4       | NULL        |  100 |   100.00 | Using index |
|  1 | SIMPLE      | bar   | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | test.foo.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)

mysql> EXPLAIN
    ->     SELECT *
    ->     FROM foo
    ->     JOIN bar USING (id)
    -> ;
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref         | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | foo   | NULL       | index  | PRIMARY       | PRIMARY | 4       | NULL        |  100 |   100.00 | Using index |
|  1 | SIMPLE      | bar   | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | test.foo.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)

mysql> EXPLAIN
    ->     SELECT *
    ->     FROM foo
    ->     JOIN bar ON foo.id = bar.id
    -> ;
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref         | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | foo   | NULL       | index  | PRIMARY       | PRIMARY | 4       | NULL        |  100 |   100.00 | Using index |
|  1 | SIMPLE      | bar   | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | test.foo.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+-------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
  • 0
    Это зависит от того, что вы делаете. Это не одно и то же, особенно ON и WHERE (например, внешнее соединение). Таким образом, вы будете использовать тот, который делает то, что вы хотите.
  • 0
    Большинство СУБД выдают ошибку, если вы используете явное JOIN без предложения ON , поэтому я бы отклонил ваш пример a JOIN b WHERE a.id = b.id по причинам переносимости. Также сбивает с толку то, что отношения ( ON ) свисают в WHERE . Что касается USING я бы привел тот же аргумент переносимости. Это также опасно близко к Natural Join , так как SQL может привести к неверным результатам после потенциально безобидного ALTER TABLE в какой-то момент в будущем. В противном случае это все синтаксический сахар и в первую очередь основанный на мнении.
Показать ещё 1 комментарий
Теги:
join

1 ответ

0

1) Для позиции USING вы должны использовать поля, которые существуют в обеих таблицах, и имеют одинаковые имена.
Но в разделе ON вы можете иметь что-то вроде:

FROM foo JOIN bar ON foo.id = bar.foo_id

2) Если вам нужно использовать определенный индекс - укажите поля, соответствующие вашему индексу (работает как для using и on).

3) Если вы используете mysql - вы можете использовать или USING либо ON либо оба они работают правильно (никто не отклоняет ни одно из этих пунктов).

Ещё вопросы

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