SQL - 内连接表的复合索引?

时间:2016-12-16 15:48:13

标签: mysql sql indexing database-design

我正在尝试创建其他索引或索引以加快下面的查询速度。所有键都是主键(表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的聚簇索引(因为查询使用了一个分组)更好?或者我可以同时使用它们吗?

1 个答案:

答案 0 :(得分:2)

截至2016年底,MySQL无法在单个查询中为任何给定的表利用多个索引。因此,添加新的单列索引并没有帮助。我想你知道的。

很难知道复合指数在没有尝试的情况下的效果如何。话虽这么说,我建议你在TableB上尝试这个索引。 (address, code, user)

为什么呢?该查询会查找codeaddress的特定值,然后汇总user。试一试。

您也可以在TableA上尝试复合索引。它将是(id, address, code)。这从id开始,因为您在WHERE上没有TableA个过滤器,并且可以通过在{{1}中扫描您的表来优化您的GROUP BY子句订单。但首先尝试id索引。

http://use-the-index-luke.com/是一个很好的参考。