Предположим, у меня есть таблица 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)
1) Для позиции USING
вы должны использовать поля, которые существуют в обеих таблицах, и имеют одинаковые имена.
Но в разделе ON
вы можете иметь что-то вроде:
FROM foo JOIN bar ON foo.id = bar.foo_id
2) Если вам нужно использовать определенный индекс - укажите поля, соответствующие вашему индексу (работает как для using
и on
).
3) Если вы используете mysql
- вы можете использовать или USING
либо ON
либо оба они работают правильно (никто не отклоняет ни одно из этих пунктов).
JOIN
без предложенияON
, поэтому я бы отклонил ваш примерa JOIN b WHERE a.id = b.id
по причинам переносимости. Также сбивает с толку то, что отношения (ON
) свисают вWHERE
. Что касаетсяUSING
я бы привел тот же аргумент переносимости. Это также опасно близко кNatural Join
, так как SQL может привести к неверным результатам после потенциально безобидногоALTER TABLE
в какой-то момент в будущем. В противном случае это все синтаксический сахар и в первую очередь основанный на мнении.