6

何百万もの行を含む大きなテーブル(TokenFrequency)があります。次のように構成されたTokenFrequencyテーブル:

表-TokenFrequency

  • id-int、主キー
  • ソース-int、外部キー
  • トークン-char
  • count-int

私の目標は、2つのソースに同じトークンが含まれているすべての行を選択することです。たとえば、私のテーブルが次のようになっている場合:

id --- source --- token --- count
1 ------ 1 --------- dog ------- 1
2 ------ 2 --- ------ cat -------- 2
3 ------ 3 --------- cat -------- 2
4 ------ 4---------豚--------
55 ------5---------動物園-------16
--- ---5---------猫--------17
------5---------豚--------1

SQLクエリでソース1、ソース2、およびカウントの合計を取得したいと思います。例えば:

source1 ---source2---トークン---カウント ----
2----------- 3 --------- cat -------- 4-
--- 2 ----------- 5 --------- cat -------- 3
---- 3 ---------- --5---------猫--------3
---- 4 -----------5---------豚- ------ 6

次のようなクエリがあります。

SELECT  F.source AS source1, S.source AS source2, F.token, 
       (F.count + S.count) AS sum 
FROM       TokenFrequency F 
INNER JOIN TokenFrequency S ON F.token = S.token 
WHERE F.source <> S.source

このクエリは正常に機能しますが、私が抱えている問題は次のとおりです。

  1. 数百万行のTokenFrequencyテーブルがあるため、この結果を取得するには、より高速な代替手段が必要です。
  2. 私が持っている現在のクエリは重複を与えています。たとえば、その選択:
    source1 = 2、source2 = 3、token = cat、count = 4
    source1 = 3、source2 = 2、token = cat、count = 4
    これはそれほど問題ではありませんが、方法がある場合それらを排除し、次に速度の増加を得るには、それは非常に便利です

私が抱えている主な問題は、現在のクエリでのクエリの速度であり、完了するまでに数時間かかります。テーブル上の内部結合自体が問題であると私は信じています。TokenFrequencyテーブルの1つのインスタンスを使用するだけで、内部結合を削除して同様の結果を得る方法が必要だと確信しています。私が言及した2番目の問題も、クエリの速度の向上を促進する可能性があります。

このクエリを再構築して、同じ結果をより速く、より効率的に提供する方法が必要です。

ありがとう。

4

3 に答える 3

3

速度の問題を診断するにはもう少し情報が必要ですが、重複を削除するには、これを WHERE に追加します。

AND F.source<S.source
于 2009-08-07T21:05:25.350 に答える
3

これを試して:

SELECT token, GROUP_CONCAT(source), SUM(count)
FROM TokenFrequency
GROUP BY token;

これにより、実行速度が大幅に向上し、重複も排除されます。ただし、ソースはカンマ区切りのリストで返されるため、アプリケーションでそれを展開する必要があります。

また、列に対して (この順序で) 複合インデックスを作成し、token, source, count分析して、MySQL がこのクエリのカバー インデックスEXPLAINとして使用できるほどスマートかどうかを確認することもできます。


更新:あなたの質問を誤解しているようです。トークンごとのカウントの合計は必要ありません。特定のトークンのソースのすべてのペアのカウントの合計が必要です。

これには内部結合が最適なソリューションだと思います。SQL の重要なガイドラインは、2 つの異なる行に関して式を計算する必要がある場合は、結合を行う必要があるということです。

ただし、前述の最適化手法の 1 つは、カバリング インデックスを使用して、必要なすべての列がインデックス データ構造に含まれるようにすることです。利点は、すべてのルックアップが O(log n) であり、物理行を読み取って他の列を取得するためにクエリで 2 番目の I/O を実行する必要がないことです。

この場合、token, source, count上で述べたように、列に対してカバリング インデックスを作成する必要があります。また、インデックスをメモリにキャッシュできるように、十分なキャッシュ領域を割り当てるようにしてください。

于 2009-08-07T21:06:33.383 に答える
2

トークンがインデックス化されていない場合は、インデックス化する必要があります。

于 2009-08-07T21:17:42.050 に答える