0

アイテムのテーブルがあり、それぞれにa_level、b_level、およびitem_idがあります。すべてのb_levelは1つのa_level専用です(例:b_level14はa_level2の「子」のみです)

何百万ものアイテムがあり、それらすべてが一度挿入されてから、SELECTのみが要求されたとします。

item_idに基づいてアイテムを選択する場合は、item_id列にインデックスを付ける必要があります。これにより、MySQLは数百万のアイテムすべてを表示しますが、これは悪いことです。私はすでにa_levelとb_levelの情報を持っているからです。したがって、特定のレベルに基づいてアイテムを選択し、その列にインデックスがある場合、MySQLは何百万ものアイテムすべてを検索する必要はなく、その特定のレベルのアイテムのみを検索する必要があります。

a_level、b_level(そしてもちろんitem_id)とSELECT WHERE a_level = b_level = item_id =の両方でインデックスを作成する場合、それは悪いことでしょうか?b_levelとitem_idのINDEXとSELECTWHEREb_level = AND item_id =だけで十分/最良の解決策になると思いますか?

それで、私はa_levelとb_level(私が言ったように任意のb_levelは1つのa_levelの「子」です)を持っているので、アイテムを拾うために作成される最も効率的なSELECTとINDEXは何でしょうか?

4

2 に答える 2

1

確かにすべての列にインデックスを付けることができます。その場合、MySQLはindex merge最適化を使用して、単一のクエリに多くのインデックスを適用します。ただし、効率を上げるために、複合インデックス(複数の列の単一のインデックス)を使用することをお勧めします。MySQL複合インデックスは、左プレフィックスルールに従って最適化に使用されます。ステートメントがインデックスの左プレフィックスに含まれる用語によって制限されている場合SELECT、そのインデックスが使用されます。たとえば、

SELECT * FROM t WHERE a_level = 1 AND b_level = 2

その場合、適切なインデックスには、最初の列として、a_levelまたはを含める必要があります。b_level言い換えると、のインデックスは、次の(a_level, b_level)ようなクエリにインデックスを付けることができます。

SELECT * FROM t WHERE a_level = 1
SELECT * FROM t WHERE a_level = 1 AND b_level = 2

だがしかし

SELECT * FROM t WHERE b_level = 2

b_levelはインデックスの左プレフィックスではないためです。

おそらく最初に、最も頻繁に実行している選択をベンチマークし、それらが左プレフィックス規則に従っている限り、それに基づいてインデックスを作成することをお勧めします。SELECTテーブル全体を覆い隠さないようにするために、いくつかの異なるクエリにいくつかのインデックスを使用することをお勧めします。データとクエリを正確に知らなければ、この質問に完全に答えることは簡単ではありません。

ただし、テーブルに二度と書き込むことがないと確信している場合は、スペースが問題にならないのであれば、全体をインデックスでカバーすることをお勧めします。

于 2011-10-12T18:52:02.607 に答える
0

列または列のセットで頻繁に選択する場合は、その列または列のセットにインデックスを付けます。インデックスは数百万のアイテムすべてを表示するわけではないため、インデックスになります(インデックスがない場合、実際には数百万のアイテムすべてが表示されます)

于 2011-10-12T18:35:32.960 に答える