【问题标题】:SQL - Compound index on inner join table?SQL - 内部连接表上的复合索引?
【发布时间】:2017-05-02 10:59:14
【问题描述】:

我正在尝试创建一个或多个附加索引来加快下面的查询。所有的键都是主键(表 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 的聚集索引(因为查询使用 group by)更好?或者我可以同时使用吗?

【问题讨论】:

  • 我认为聚集索引可能是指复合索引。聚集索引是 SQL Server 中的东西,但不是 MySQL。
  • PRIMARY KEY(address, code) 既是“复合”(又名“复合”)又是集群的。在 InnoDB 中,根据 MySQL 的定义,PK 是唯一的和集群的。
  • 这是dba.stackexchange.com/questions/158385/… 的副本,到目前为止只有一个答案。
  • 不要交叉发布。标记迁移或关闭此问题。

标签: mysql sql indexing database-design


【解决方案1】:

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

如果不尝试,很难知道复合索引的效果如何。话虽如此,我建议您在TableB 上尝试此索引。 (address, code, user)?

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

您也可以在TableA 上尝试复合索引。应该是(id, address, code)。这以id 开头,因为您在TableA 上没有任何WHERE 过滤器,并且您的GROUP BY 子句可以通过按id 顺序扫描您的表来优化。但请先尝试TableB 索引。

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

【讨论】:

  • 感谢您的建议,实际上我对数据库比较陌生,目前这些概念仍然有点难以理解。
  • 既然我有一个按指令分组,那么在表 A 上为 id 设置一个聚集索引不是可取的吗?
  • 或者,通过将 user 放在最后来重新排列您的 PK。
猜你喜欢
  • 2013-12-01
  • 2011-01-19
  • 2013-06-09
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 2012-06-03
相关资源
最近更新 更多