1

这是第一个表“tbl1”:

+---------+---------------------+------+-----+---------+----------------+
| Field   | Type                | Null | Key | Default | Extra          |
+---------+---------------------+------+-----+---------+----------------+
| val     | varchar(45)         | YES  | MUL | NULL    |                |
| id      | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
+---------+---------------------+------+-----+---------+----------------+

用它的索引:

+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tbl1  |          0 | PRIMARY  |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl1  |          1 | val      |            1 | val         | A         |     2147085 |     NULL | NULL   | YES  | BTREE      |         |
| tbl1  |          1 | id_val   |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl1  |          1 | id_val   |            2 | val         | A         |   201826018 |     NULL | NULL   | YES  | BTREE      |         |
| tbl1  |          1 | val_id   |            1 | val         | A         |     2147085 |     NULL | NULL   | YES  | BTREE      |         |
| tbl1  |          1 | val_id   |            2 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

(一些额外索引的原因是: http: //bit.ly/KWx1Xz。)

第二张桌子也差不多。以下是它的索引基数:

+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tbl2   |          0 | PRIMARY  |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl2   |          1 | val      |            1 | val         | A         |      881336 |     NULL | NULL   | YES  | BTREE      |         |
| tbl2   |          1 | id_val   |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl2   |          1 | id_val   |            2 | val         | A         |   201826018 |     NULL | NULL   | YES  | BTREE      |         |
| tbl2   |          1 | val_id   |            1 | val         | A         |      881336 |     NULL | NULL   | YES  | BTREE      |         |
| tbl2   |          1 | val_id   |            2 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

任务是将它们内部连接到 val 列并获取 id 的列表(并在 1 秒内完成)。

这是“加入”方法:

SELECT tbl1.id FROM tbl1 JOIN tbl2 ON tbl1.val = 'iii' AND tbl2.val = 'iii' AND tbl1.id = tbl2.id;

结果:集合中有 10831 行(55.15 秒

查询说明:

+----+-------------+--------+--------+----------------------------------+---------+---------+---------------------------+------+--------------------------+
| id | select_type | table  | type   | possible_keys                    | key     | key_len | ref                       | rows | Extra                    |
+----+-------------+--------+--------+----------------------------------+---------+---------+---------------------------+------+--------------------------+
|  1 | SIMPLE      | tbl1   | ref    | PRIMARY,val,id_val,val_id        | val_id  | 138     | const                     | 5160 | Using where; Using index |
|  1 | SIMPLE      | tbl2   | eq_ref | PRIMARY,val,id_val,val_id        | PRIMARY | 8       | search_test.tbl1.id       | 1    | Using where              |
+----+-------------+--------+--------+----------------------------------+---------+---------+---------------------------+------+--------------------------+

这是'in'方法:

SELECT id FROM tbl1 WHERE val = 'iii' and id IN (SELECT id FROM tbl2 WHERE val = 'iii');

结果:集合中有 10831 行(1 分 10.15 秒

解释:

+----+--------------------+--------+-----------------+---------------------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table  | type            | possible_keys                   | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+--------+-----------------+---------------------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | tbl1   | ref             | val,val_id                      | val_id  | 138     | const | 8553 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | tbl2   | unique_subquery | PRIMARY,val,id_val,val_id       | PRIMARY | 8       | func  |    1 | Using where              |
+----+--------------------+--------+-----------------+---------------------------------+---------+---------+-------+------+--------------------------+

那么,问题来了:如何调整这个查询让 MySQL 在一秒钟内完成它?

4

2 回答 2

2
SELECT tbl1.id FROM tbl1 JOIN tbl2 ON tbl1.id = tbl2.id and tbl1.val = tbl2.val
where tbl1.val = 'iii';
于 2012-06-12T20:53:27.250 回答
2

好的,我已经在每个表的 30,000 多条记录上进行了测试,它运行得非常快。

按照目前的情况,您目前正在对两个大型表执行连接,但是如果您首先在每个表上扫描“val”上的匹配项,这将大大减少连接集的大小。

我最初将这个答案发布为一组子查询,但我没有意识到 MySQL 在嵌套子查询中的速度非常慢,因为它是从外向内执行的。但是,如果将子查询定义为视图,它会从内向外运行它们。

因此,首先创建视图。

CREATE VIEW tbl1_iii AS (
SELECT * FROM tbl1 WHERE val='iii'
);
CREATE VIEW tbl2_iii AS (
SELECT * FROM tbl2 WHERE val='iii'
);

然后运行查询。

SELECT tbl1_iii.id from tbl1_iii,tbl2_iii
WHERE tbl1_iii.id = tbl2_iii.id;

闪电。

于 2012-06-12T21:17:15.707 回答