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

标签 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 的聚集索引(因为查询使用了分组依据)更好?或者我可以同时使用两者吗?

最佳答案

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

不尝试就很难知道复合索引的效果如何。话虽这么说,我建议您在 TableB 上尝试这个索引。 (地址、代码、用户)

为什么?该查询查找codeaddress 的特定值,然后汇总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/

相关文章:

MySQL 查询按多列排序

sql - 我怎样才能得到每列的总和?

mysql - COUNT 比常规选择慢得多

sql - 优化以通配符开头的 LIKE 表达式

MySQL 存储过程调试输出

php - Laravel 需要获取每条评论的用户名

mysql - mysql数据库的日志文件

php - 关于 MySQL/PHP 中事务(或表锁?)的问题

sql - 是否可以反编译和读取 SSIS 包代码?

indexing - 乌鸦数据库 4 RC2 : Cannot execute command of type PutAutoIndexCommand for database - Can not update auto-index: