2

このクエリを高速化するために考えられるすべてのことを試しましたが、それでも約2.5秒かかります。

テーブルはimages_tags(〜400万行)です:テーブルの説明は次のとおりです。

Field       Type               Null     Key     Default
image_ids   int(7) unsigned    NO       PRI     NULL
tags_id     int(7) unsigned    NO       PRI     NULL

インデックスは次のとおりです。

Table         Non_unique  Key_name      Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null  Index_type
images_tags   0           PRIMARY       1             image_ids    A          NULL         NULL      NULL          BTREE
images_tags   0           PRIMARY       2             tags_id      A          4408605      NULL      NULL          BTREE
images_tags   1           image_ids     1             image_ids    A          734767       NULL      NULL          BTREE

そしてここにクエリがあります:

select image_ids
from images_tags
where tags_id in (1, 2, 21, 846, 3175, 4290, 6591, 9357, 9594, 14289, 43364, 135019, 151295, 208803, 704452)
group by image_ids
order by count(*) desc
limit 10

そして、これがクエリEXPLAINです。

select_type  table        type   possible_keys  key                 key_len  ref   rows     Extra
SIMPLE       vids_x_tags  index  join_tags_id   join_vids_id_unique  8       NULL  4408605  Using where; Using index; Using temporary; Using filesort

目標は、これらのタグに最も一致する10枚の画像を取得することです。私はこれらの変数をいじってみましたが、ほとんどまたはまったく改善されていません。

  • max_heap_table_size
  • tmp_table_size
  • myisam_sort_buffer_size
  • read_buffer_size
  • sort_buffer_size
  • read_rnd_buffer_size
  • net_buffer_length
  • preload_buffer_size
  • key_buffer_size

このクエリを大幅に高速化する方法はありますか?約70万枚の画像があり、常に増え続けているので、結果を1日か2日以上キャッシュしたくありません。また、画像ごとに実行する必要があるため、多くのクエリを再キャッシュすることは不可能です。

4

2 に答える 2

1

この種のリンク (ジャンクション、多対多) テーブルでは、ほとんどの場合、 と の両方に 2 つの複合インデックスがあると便利(a, b)です(b, a)。それらのうちの 1 つ (プライマリ インデックス) だけがあり、他のインデックスはありません。

また、テーブルに他の列がない場合は、他のインデックスはまったく必要ありません。

したがって、(tags_id, image_ids)インデックスを追加し、(image_ids)冗長なものを削除する必要があります。

ALTER TABLE images_tags
  DROP INDEX image_ids,
  ADD INDEX tag_image_IDX           -- choose a name for the index
    (tags_id, image_ids) ;

特定のクエリに関するインデックスの効率は、多くの要因に依存し、主に画像とタグの分布に依存します (INリストにある 15 個のタグの人気はどれくらいですか?)

于 2012-09-26T07:00:19.863 に答える
1

クエリの出力では、列がリストのどの項目とも一致しないEXPLAINことがわかります。これは、データがインデックスからフェッチされたにもかかわらず (多くの場合、実際のテーブルよりも小さい列にまたがる)、エンジンはすべての行を走査しなければならなかったことを意味します。keypossible_keys

インデックスを適切に使用してこのクエリを高速化したい場合は、タグを最初の(そしておそらく唯一の) コンポーネントとして追加する必要があります。

ちなみに、image_ids主キーを使用してその情報を提供することもできるため、インデックス on only はほとんど役に立ちません。一般に、複数の行に対するインデックスを使用して、これらすべての列、または最初から始まる列の連続セットのいずれかに明示的な値 (または範囲) を提供するクエリを高速化できます。つまり、2 列のインデックスは、最初の列でも 1 列のインデックスのように機能しますが、2 番目の列だけではあまり役に立ちません。

tags_idにキーを追加して にキーをドロップする代わりに、キーをそのままにして、主キーの列の順序を逆にするimage_idsことができます。image_ids次に、主キーを使用して、タグのみのクエリに回答することもできます。画像よりもタグでテーブルを頻繁にクエリする場合は、このアプローチをお勧めします。

于 2012-09-26T07:00:47.240 に答える