2009-07-31 9 views
1

現在、 'item'テーブルと 'pair'テーブルがあります。ペアテーブルには、項目テーブルの主キーを含む2つの列が含まれています。効率よくインデックスを作成するためのMySQLテーブル構造の整​​理

よくある質問は、最も少ない数のペアに含まれるアイテムの数を見つけることです。

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

が、クエリがhoribleパフォーマンスが賢明です。 id1、id2にはペアのインデックスがあります。

+----+-------------+-------+-------+---------------+------+---------+------+-------+---------------------------------+ 
| 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      | 
+----+-------------+-------+-------+---------------+------+---------+------+-------+---------------------------------+ 

このタイプのものには、より良いクエリやデータ構造がありますか?

答えて

1

(あなたは(ID1、ID2)インデックスの一部として無料でID1のインデックスを取得):

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

と、このようクエリを書き直す:

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

ありがとう、それは素晴らしい作品!!!! '私はSELECT id、COUNT(p1.id1)+ COUNT(p2.id2)からアイテムをカウントしました。LEFT JOINペアp1 ON(i.id = p1.id1)LEFT JOINペアp2 .id = p2.id2)GROUP BY id ORDER BY count、RAND()LIMIT 100'これは合理的にうまくいった。しかし、サブクエリの方が高速なので、2つのサブクエリをインデックスだけで解くことができます。 – barryhunter

0

(id1、id2)にインデックスがある場合は、id2とのマッチングが行われている場合は、id2にインデックスを付ける必要があります。あなたがpair上の2つのインデックスを作成する必要が

+0

私はそれを試しましたが、上記の質問に何か違いはありませんでした。 (私はそれが2つのインデックスを使用して理解する1つの/句が動作しない単一のを満たすために) – barryhunter

関連する問題