5

つまり、基本的に、URLとTAGSを含む2つのテーブルがあり、結合テーブルTAGS_URLSを介して2つの間にhas-and-belongs-to-manyの関係があります。

タグでURLを検索する簡単なクエリは次のようになります。

SELECT urls.id FROM urls 
  INNER JOIN tags_urls ON urls.id=tags_urls.url_id
  INNER JOIN tags ON tags_urls.tag_id=tags.id 
WHERE tags.tag IN ("sample","tag","list");

ただし、すべてのタグセットを含むすべてのURLの共通部分を復元しようとしています。つまり、タグ「sample」AND「tag」AND「list」を含むURLのみです。

動作するクエリがありますが、30秒以内にクエリを実行できません。

SELECT a.id
  FROM
    (SELECT DISTINCT urls.id FROM urls
      INNER JOIN tags_urls ON tags_urls.url_id=urls.id INNER JOIN tags ON tags.id=tags_urls.tag_id
      WHERE tags.tag = 'sample') a
  JOIN
     (SELECT DISTINCT urls.id FROM urls
      INNER JOIN tags_urls ON tags_urls.url_id=urls.id INNER JOIN tags ON tags.id=tags_urls.tag_id
      WHERE tags.tag = 'list') b
  ON a.id = b.id;

結果セットは正しいですが、パフォーマンスは恐ろしいものです。

また、現在、タグセットに保存されているURL IDのリストとしてRedisデータベースにデータを複製しているので、このようなことを実行して、非常に迅速に結果セットを取得できます。

SINTER "tag-sample" "tag-list"

合理的な努力で、このタスクのMySQLパフォーマンスをSINTERを使用してRedisレベルまで上げることは可能でしょうか?

4

2 に答える 2

1

100%確信はありませんが、基盤となるエンジンは、サブセレクトごとに一時テーブルを作成していると思います。データのサイズによっては、これにはかなりのコストがかかる可能性があります。それらが大きい場合(そしてあなたの場合はそうです)、一時テーブルは大きすぎて一度にメモリに保持できないため、その内容をディスクに書き出す必要があります。したがって、基本的にクエリは、2つの副選択の選択基準に一致する2つの一時テーブルを作成しようとするため、大量のデータをコピーします。これが行われると、最終的に外側の選択が実行され、これはおそらくかなり高速です。

内部結合の副選択を除外しようとします。私は以下があなたが探しているものをあなたに与えると思います:

select urls.id from urls
inner join tags_urls tu1 on tu1.url_id = urls.id
inner join tags t1 on tu1.tag_id = t1.id and t1.tag = 'sample'
inner join tag_urls tu2 on tu2.url_id = urls.id
inner join tags t2 on t2.id = tu2.tag_id and t2.tag = 'list'

交差させたい「タグ」ごとに、tag_urlsとタグに内部結合のペアを追加し続けます。繰り返しますが、これをexplainに実行し、すべてが正しいインデックスを持っていることを確認してください。

DBMSは、いくつかの内部結合でかなりうまく機能しますが、交差の数を増やすと、パフォーマンスが低下します。

于 2011-04-15T23:05:23.307 に答える
0

2番目のstatmenetのsqlサブクエリを結合に置き換えてみてください。Robert Vieiraは、SQL Serverの本で、結合が高速である場合とサブクエリが高速である場合があると主張しています。同じことがMySqlにも当てはまらないとは信じがたい。また、テーブルに「list」または「sample」以外のデータがかなりある場合は、このデータを一時テーブルに挿入し、代わりにそのテーブルからクエリを実行することをお勧めします。これは、そのデータに対して複数のクエリを実行する場合に特に当てはまります。

于 2011-04-15T22:49:33.483 に答える