2009-07-29 9 views
3

ich zwei Tabellen haben, TableA und TableB:Wie verhindert man einen vollständigen Tabellenscan bei einem einfachen JOIN?

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 

Hier ist meine Frage:

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

Hier ist das 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 | 
+----+-------------+--------------+--------+---------------+---------+---------+------------------------------------------+------+-------------+ 

Gibt es ein Index, den ich hinzufügen kann das wird den vollständigen Tabellenscan von TableB verhindern?

Antwort

2

Runcible, könnte Ihre Abfrage einige Umschreiben verwenden. Sie sollten Ihre JOIN-Bedingungen immer in einer ON-Klausel und nicht in einer WHERE angeben.

Ihre Anfrage würde:

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

Nicht nur Sie dies tun wollen:

ALTER TABLE TableB ADD INDEX (shared_id,bar); 

Sie werden einen Index A hinzugefügt werden soll, wie folgt:

ALTER TABLE TableA ADD INDEX (foo, shared_id); 

Tun Sie dies und stellen Sie bitte die EXPLAIN-Ausgabe bereit.

Beachten Sie auch, dass Sie Ihren Index (shared_id) einfach redundant gemacht haben, indem Sie einen Index auf (shared_id, bar) hinzufügen. Lass es fallen.

+0

Das Hinzufügen des zweiten Index hat den Trick gemacht. @hobodave: Danke für deine Hilfe! – Runcible

+0

@Ausgabe erklären? – briankip

Verwandte Themen