4 Stimmen

Wie kann man eine vollständige Tabellendurchsuchung bei einem einfachen JOIN verhindern?

Ich habe zwei Tabellen, TabelleA und TabelleB:

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 Anfrage:

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 einen Index, den ich hinzufügen kann, der die vollständige Tabellendurchsuchung von TabelleB verhindern wird?

3voto

hobodave Punkte 28128

Runcible, Ihre Anfrage könnte etwas umgeschrieben werden. Sie sollten Ihre JOIN-Bedingungen immer in einer ON-Klausel und nicht in einer WHERE-Klausel angeben.

Ihre Frage würde dann lauten:

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

Das wollen Sie nicht nur tun:

ALTER TABLE TableB ADD INDEX (shared_id,bar);

Fügen Sie einen Index zu A wie folgt hinzu:

ALTER TABLE TableA ADD INDEX (foo, shared_id);

Führen Sie dies durch und stellen Sie bitte die EXPLAIN-Ausgabe zur Verfügung.

Beachten Sie auch, dass Sie durch das Hinzufügen eines Indexes auf (shared_id, bar) Ihren Index (shared_id) überflüssig gemacht haben. Lassen Sie ihn fallen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X