3

これが私のクエリです:

select word_id, count(sentence_id) 
from sentence_word 
group by word_id 
having count(sentence_id) > 100;

テーブルの文語には、wordid、文 ID、および主キー ID の 3 つのフィールドが含まれています。35万行以上あります。このクエリにはなんと 85 秒かかりますが、100 を超えるセンテンス ID を持つすべてのワード ID を見つけるためのより高速な方法があるのではないかと考えています (願っていますか、祈っていますか?)。

select count の部分を取り出して、'having count(1)' を実行してみましたが、どちらも速度が上がりません。

あなたが貸してくれる助けをいただければ幸いです。ありがとう!

4

5 に答える 5

6

まだ持っていない場合は、sentence_id、word_id に複合インデックスを作成します。

于 2009-05-04T05:36:20.357 に答える
3

count(sentence_id)>100;

これには問題があります...テーブルに重複する単語/文のペアがあるか、ないかのどちらかです。

単語と文のペアが重複している場合は、次のコードを使用して正しい答えを取得する必要があります。

HAVING COUNT(DISTINCT Sentence_ID) > 100

テーブルに重複する単語/文のペアがない場合...sentence_idsをカウントするのではなく、行をカウントするだけです。

HAVING COUNT(*) > 100

この場合、最適なパフォーマンスを得るために、 word_idのみにインデックスを作成できます。

于 2009-05-04T14:57:44.110 に答える
1

そのクエリが頻繁に実行され、テーブルがめったに更新されない場合は、単語 ID と対応する文数を含む補助テーブルを保持できます。それ以上の最適化は考えにくいです。

于 2009-05-04T05:34:09.690 に答える
1

クエリは問題ありませんが、より高速な結果を得るには、少し助け (インデックス) が必要です。

手持ちのリソース (または SQL へのアクセス) はありませんが、記憶からお手伝いします。

概念的には、そのクエリに答える唯一の方法は、同じ word_id を共有するすべてのレコードを数えることです。つまり、クエリ エンジンには、これらのレコードをすばやく検索する方法が必要です。word_id にインデックスがない場合、データベースができる唯一のことは、一度に 1 レコードずつテーブルを調べて、見つかったすべての個別の word_id の合計を実行し続けることです。これには通常、一時テーブルが必要であり、テーブル全体がスキャンされるまで結果をディスパッチできません。良くない。

word_id にインデックスがある場合でも、テーブルを通過する必要があるため、あまり役に立たないと思うでしょう。ただし、SQL エンジンは、テーブルの最後まで待たずに各 word_id のカウントを計算できるようになりました。行とその word_id の値のカウントをディスパッチしたり (where句を通過した場合)、行を破棄したり (しない); これにより、サーバーのメモリ負荷が低下し、部分的な応答が発生する可能性があり、一時テーブルは不要になります。2 つ目の側面は並列性です。word_id のインデックスを使用すると、SQL はジョブをチャンクに分割し、個別のプロセッサ コアを使用してクエリを並行して実行できます (ハードウェアの機能と既存のワークロードによって異なります)。

あなたのクエリを助けるにはそれで十分かもしれません。ただし、次のことを確認する必要があります。

CREATE INDEX someindexname ON sentence_word (word_id)

(T-SQL 構文。使用している SQL 製品を指定していません)

これで十分でない (またはまったく役に立たない) 場合は、他に 2 つの解決策があります。

まず、SQL では、インデックス付きビューやその他のメカニズムを使用して、COUNT(*) を事前に計算できます。私は詳細を手元に持っていません (そして、私はこれを頻繁に行うわけではありません)。データが頻繁に変更されない場合は、より高速な結果が得られますが、複雑さと少しのストレージのコストがかかります。

また、クエリの結果を別のテーブルに格納することを検討することもできます。これは、データがまったく変更されない場合、または正確なスケジュールに従って変更される場合 (たとえば、午前 2 時のデータ更新中)、または変更がほとんどなく、完全ではない結果が数時間続く可能性がある場合にのみ実用的です (定期的なデータ更新をスケジュールする必要があります); これは、貧乏人のデータ ウェアハウスに相当する道徳的なものです。

何が適切かを確認する最善の方法は、クエリを実行し、上記のような候補インデックスがある場合とない場合のクエリ プランを確認することです。

于 2009-05-04T06:06:10.020 に答える
0

驚くべきことに、大規模なデータ セットでこれを行うためのさらに高速な方法があります。

SELECT totals.word_id, totals.num 
  FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
 WHERE num > 1000;
于 2010-10-05T01:02:38.917 に答える