2009-07-31 8 views
1

Momentan gibt es eine "Item" -Tabelle und eine "Pair" -Tabelle. Die Paartabelle enthält einfach zwei Spalten, die den Primärschlüssel aus der Item-Tabelle enthalten.Organisieren einer MySQL-Tabellenstruktur zum effizienten Indexieren von Paaren

Eine häufige Abfrage besteht darin, eine Anzahl von Elementen zu finden, die in der geringsten Anzahl von Paaren vorkommen.

SELECT id,COUNT(*) AS count FROM item i LEFT JOIN pair p ON (i.id = p.id1 OR i.id = p.id2) GROUP BY id ORDER BY count,RAND() LIMIT 100

aber die Abfrage weise horible Leistung. Es gibt einen Index für ID1, ID2 für Paar.

+----+-------------+-------+-------+---------------+------+---------+------+-------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra       | 
+----+-------------+-------+-------+---------------+------+---------+------+-------+---------------------------------+ 
| 1 | SIMPLE  | item | ALL | NULL   | NULL | NULL | NULL | 5644 | Using temporary; Using filesort | 
| 1 | SIMPLE  | pair | index | id1   | id1 | 8  | NULL | 18377 | Using index      | 
+----+-------------+-------+-------+---------------+------+---------+------+-------+---------------------------------+ 

Gibt es eine bessere Abfrage und/oder Datenstruktur für diese Art von Sache?

Antwort

1

Sie benötigen zwei Indizes zu erstellen, die auf pair:

CREATE INDEX ix_pair_1 ON pair (id1) 
CREATE INDEX ix_pair_2 ON pair (id2) 

und schreiben Sie Ihre Abfrage wie folgt aus:

SELECT (
     SELECT COUNT(*) 
     FROM pair 
     WHERE id1 = i.id 
     ) + 
     (
     SELECT COUNT(*) 
     FROM pair 
     WHERE id2 = i.id 
     ) AS cnt 
FROM item i 
ORDER BY 
     cnt, RAND() 
LIMIT 100 
+0

Danke, das funktioniert super !!!! 'Ich hatte es als SELECT ID versucht, COUNT (p1.id1) + COUNT (p2.id2) AS Anzahl FROM Artikel i LINKE JOIN Paar p1 ON (i.id = p1.id1) LINKE JOIN Paar p2 (i .id = p2.id2) GROUP BY id ORDER BY count, RAND() LIMIT 100' was einigermaßen gut funktioniert hat. Aber als Unterabfragen sind Größen schneller - Raten der beiden Unterabfragen können nur aus den Indizes beantwortet werden. – barryhunter

0

Wenn Sie einen Index für (ID1, ID2) haben, sollten Sie auch einen Index für ID2 haben, für die Fälle, in denen Sie selbst mit ID2 übereinstimmen. (Sie erhalten einen Index für id1 kostenlos als Teil des (ID1, ID2) Index)

+0

Ich versuchte das, machte keinen Unterschied auf die obige Abfrage tho. (wie ich es verstehe mit zwei Indizes zu erfüllen, eine einzige where/on-Klausel funktioniert nicht) – barryhunter

Verwandte Themen