How to prevent a full table scan while executing a simple JOIN?

I have two tables: TableA and 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 is my request:

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 I can add that will prevent a full scan of the TableB table?

+3
source share
1 answer

Runcible, your request may use some rewriting. You should always specify your JOIN clauses in the ON clause, and not in the WHERE clause.

Your request will look like this:

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

You not only want to do this:

ALTER TABLE TableB ADD INDEX (shared_id,bar);

You need to add the index as follows:

ALTER TABLE TableA ADD INDEX (foo, shared_id);

Do this and specify the output of EXPLAIN.

Also note that by adding an index to (shared_id, bar), you just made your (shared_id) index redundant. Throw it.

+2

Source: https://habr.com/ru/post/1713911/


All Articles