Я пытаюсь создать дополнительный индекс или индексы, чтобы ускорить запрос ниже. Все ключи являются первичными ключами (за исключением идентификатора в таблице A), поэтому они уже имеют связанный с ними индекс btree по умолчанию. id в таблице A также имеет индекс, уже связанный с ним, поскольку его ключ MUL означает, что он является частью уникального индекса.SQL - Составной индекс на внутренней таблице соединений?
Select A.id
From TableA A
Inner join TableB B
On A.address = B.address
And A.code = B.code
Group by A.id
Having count(distinct B.user) = 1;
Это текущий индекс на вышеуказанных таблицах:
mysql> show index from TableA;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| TableA | 0 | PRIMARY | 1 | address | A | 8 | NULL | NULL | | BTREE | |
| TableA | 0 | PRIMARY | 2 | code | A | 24 | NULL | NULL | | BTREE | |
| TableA | 1 | id | 1 | id | A | 8 | NULL | NULL | | BTREE | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
mysql> show index from TableB;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| TableB | 0 | PRIMARY | 1 | user | A | 9 | NULL | NULL | | BTREE | |
| TableB | 0 | PRIMARY | 2 | address | A | 9 | NULL | NULL | | BTREE | |
| TableB | 0 | PRIMARY | 3 | code | A | 9 | NULL | NULL | | BTREE | |
| TableB | 1 | address | 1 | address | A | 9 | NULL | NULL | | BTREE | |
| TableB | 1 | address | 2 | code | A | 9 | NULL | NULL | | BTREE | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
Запрос объяснить штатам это:
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | F | index | address | address | 514 | NULL | 9 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | A | eq_ref | PRIMARY | PRIMARY | 514 | db.B.address,db.B.code | 1 | |
+----+-------------+-------+--------+---------------+---------+---------+---------------------------------------+------+----------------------------------------------+
У меня возникли проблемы с пониманием того, что я должен делать. Является ли составной индекс адреса и кода единственным, что я мог бы сделать, чтобы улучшить скорость упомянутого запроса?
Или представляет собой кластерный индекс id (поскольку запрос использует группу by) лучше? Или я мог бы использовать оба?
Я думаю, что * сгруппированный индекс * вы можете означать * составной индекс *. Кластеризованные индексы - это вещи на SQL-сервере, но не в MySQL. –
'ПЕРВИЧНЫЙ КЛЮЧ (адрес, код)' является как «композитным» (aka «составным»), так и сгруппированным. В InnoDB PK по определению MySQL уникален и сгруппирован. –
Это дубликат http://dba.stackexchange.com/questions/158385/compound-index-on-inner-join-table, который имеет один ответ до сих пор. –