简体   繁体   English

如何在进行简单的JOIN时阻止全表扫描?

[英]How to prevent a full table scan when doing a simple JOIN?

I have two tables, TableA and TableB: 我有两个表,TableA和TableB:

CREATE TABLE `TableA` (
  `shared_id` int(10) unsigned NOT NULL default '0',
  `foo` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`shared_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1


CREATE TABLE `TableB` (
  `shared_id` int(10) unsigned NOT NULL auto_increment,
  `bar` int(10) unsigned NOT NULL,
  KEY `shared_id` (`shared_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1001 DEFAULT CHARSET=latin1 

Here's my query: 这是我的查询:

SELECT TableB.bar 
FROM TableB, TableA 
WHERE TableA.foo = 1000 
AND TableA.shared_id = TableB.shared_id;

Here's the problem: 这是问题所在:

mysql> explain SELECT TableB.bar FROM TableB, TableA WHERE TableA.foo = 1000 AND TableA.shared_id = TableB.shared_id;

+----+-------------+--------------+--------+---------------+---------+---------+------------------------------------------+------+-------------+
| id | select_type | table        | type   | possible_keys | key     | key_len | ref                                      | rows | Extra       |
+----+-------------+--------------+--------+---------------+---------+---------+------------------------------------------+------+-------------+
|  1 | SIMPLE      | TableB       | ALL    | shared_id     | NULL    | NULL    | NULL                                     | 1000 |             |
|  1 | SIMPLE      | TableA       | eq_ref | PRIMARY       | PRIMARY | 4       | MyDatabase.TableB.shared_id              |    1 | Using where |
+----+-------------+--------------+--------+---------------+---------+---------+------------------------------------------+------+-------------+

Is there an index that I can add that will prevent the full table scan of TableB? 是否有我可以添加的索引将阻止TableB的全表扫描?

Runcible, your query could use some rewriting. Runcible,您的查询可能会使用一些重写。 You should always specify your JOIN conditions in an ON clause and not in a WHERE. 您应该始终在ON子句中而不是在WHERE中指定JOIN条件。

Your query would become: 您的查询将变为:

SELECT TableB.bar 
FROM TableB
JOIN TableA
ON TableB.shared_id = TableA.shared_id
AND TableA.foo = 1000;

Not only do you want to do this: 你不仅想要这样做:

ALTER TABLE TableB ADD INDEX (shared_id,bar);

You'll want to add an index to A as follows: 您需要为A添加索引,如下所示:

ALTER TABLE TableA ADD INDEX (foo, shared_id);

Do this, and provide the EXPLAIN output please. 这样做,请提供EXPLAIN输出。

Also note that by adding an index on (shared_id, bar) you just made your (shared_id) index redundant. 另请注意,通过在(shared_id,bar)上添加索引,您只需使(shared_id)索引冗余。 Drop it. 算了吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM