结合两个快速索引查询会使结果变慢

时间:2016-10-12 14:16:10

标签: mysql

我有两张桌子A和B.

表A

guid | username
---------------
  A  |  name1
  B  |  name2
  C  |  name3

使用索引

+--------+------------+-------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name                      | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+-------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tableA |          0 | PRIMARY                       |            1 | guid         | A         |     2242900 |     NULL | NULL   |      | BTREE      |         |               |
+--------+------------+-------------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

表B

guidA | guidB
-------------
  A   |   C
  B   |   C

使用索引

+----------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name            | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tableB   |          1 | guidA_idx           |            1 | userid      | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
| tableB   |          1 | guidB_idx           |            1 | userid      | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+---------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

我想要的是在给定 guidB 的情况下进行查询我获取相应 {{1}的 username }

仅从表A中选择其快速..

guidA

使用DESC

select guid from tableA where guid IN ('A', 'B');

从表B​​中选择也很快......(它只有三行,所以没有使用索引)

+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | tableA  | range | PRIMARY       | PRIMARY | 66      | NULL |    3 | Using where; Using index |
+----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+

DESC

select guidA from tableB where guidB = 'C';

然而!如果我做

+----+-------------+--------+------+--------------+------+---------+------+------+-------------+
| id | select_type | table  | type | possible_keys| key  | key_len | ref  | rows | Extra       |
+----+-------------+--------+------+--------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tableB | ALL  | guidB_idx    | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+--------+------+--------------+------+---------+------+------+-------------+

我得到了正确的结果,但查询速度很慢,因为tableA中的guid索引从未使用过。

DESC

select guid, username from tableA where guid IN (select guidA from tableB where guidB = 'C');

正如您所看到的,它可以进行全表扫描。我在某处读到使用+----+-------------+--------+------+---------------------+------+---------+------+---------+-------------------------------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------------+------+---------+------+---------+-------------------------------------------------------------------------+ | 1 | SIMPLE | tableA | ALL | NULL | NULL | NULL | NULL | 2242900 | NULL | | 1 | SIMPLE | tableB | ALL | guidA_idx,guidB_idx | NULL | NULL | NULL | 3 | Using where; FirstMatch(tableA); Using join buffer (Block Nested Loop) | +----+-------------+--------+------+---------------------+------+---------+------+---------+-------------------------------------------------------------------------+ 有优化问题,但重写查询为 WHERE IN (subquery) 并没有给出不同的结果。我总是在LEFT JOIN, RIGHT JOIN, or INNER JOIN上进行全表扫描。我每次都得到正确的结果。

加入...

tableA

我的MySQL版本 Ver 14.14 Distrib 5.6.28,for Win64(x86_64)

1 个答案:

答案 0 :(得分:1)

您的列必须具有相同的类型和排序规则。

不同的排序规则或不同类型将避免使用任何索引。