我正在尝试创建一个或多个附加索引来加速下面的查询。所有键都是主键(表 A 上的 id 除外),因此它们已经有一个与之关联的默认 btree 索引。表 A 上的 id 也有一个已与其关联的索引,因为它是 MUL 键,这意味着它是非唯一索引的一部分。
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 的聚集索引(因为查询使用了分组依据)更好?或者我可以同时使用两者吗?
最佳答案
截至 2016 年底,MySQL 无法在单个查询中对任何给定表使用多个索引。因此,添加新的单列索引没有帮助。我想你知道这一点。
不尝试就很难知道复合索引的效果如何。话虽这么说,我建议您在 TableB
上尝试这个索引。 (地址、代码、用户)
?
code
和address
的特定值,然后汇总user
。尝试一下。
您也可以在 TableA
上尝试复合索引。它将是(id,地址,代码)
。这以 id
开头,因为您在 TableA
上没有任何 WHERE
过滤器,并且您的 GROUP BY
子句可以通过按 id
顺序扫描表格来进行优化。但首先尝试 TableB
索引。
http://use-the-index-luke.com/是一个很好的引用。
关于mysql - SQL - 内连接表上的复合索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41187911/