0

3,000 万行以上のデータベース テーブル UserRewards があります。この行には、ユーザー ID と、行ごとに (他のフィールドと共に) 報酬 ID があります。

ユーザー テーブル (約 400 万の一意のユーザーを持つ) があり、プライマリ キーの userID とその他のフィールドがあります。パフォーマンス上の理由から、userrewards のユーザーごとのrewardID を users の連結フィールドに移動したいと考えています。(Rewards と呼ばれる新しい nvarchar(4000) フィールド) これをできるだけ速く実行できるスクリプトが必要です。

以下のスクリプトを使用して報酬を結合するカーソルがありますが、1 分あたり約 100 人のユーザーしか処理できず、約 400 万人のユニーク ユーザーを取得するには時間がかかりすぎます。

 set @rewards = ( select REPLACE( (SELECT rewardsId AS [data()] from userrewards
 where UsersID = @users_Id and BatchId = @batchId
       FOR XML PATH('')  ), ' ', ',') )

これを最適化するための提案はありますか? while ループを試してみようとしているので、それがどのように機能するかを確認しますが、他のアイデアは大歓迎です。

編集:

私のサイトは次のことを行います。

5 ~ 10 の「賞」が事前に割り当てられている約 400 万人のユーザーがいます。この関係は userrewards テーブルにあります。

ユーザーがサイトにアクセスすると、ユーザーを識別し、データベースでユーザーに割り当てられた報酬を検索します。

問題は、サイトが非常に人気があるため、多数の人が同時にサイトにアクセスしてデータを要求していることです。上記は結合を減らしますが、これが最善の解決策ではないことを理解しています. サイトをオンにしてから 10 秒以内にデータベース サーバーの CPU 使用率が 100% に達するため、ほとんどのユーザーの要求はタイムアウトする (エラー ページが表示される) か、結果は得られますが満足のいく時間ではありません。

私の問題に対するより良い解決策を提案できる人はいますか?

4

2 に答える 2

1

あなたが試みているアプローチが悪い考えだと思う理由はいくつかあります。まず、users テーブルでカンマ区切りのリストをどのように維持するのでしょうか? 報酬は夜などに一括で読み込まれる可能性があるため、これは今のところ問題にはなりません。それでも、ある日、報酬をより頻繁に割り当てたいと思うかもしれません。

次に、報酬を削除したり、名前を変更したりしたい場合はどうなりますか? 1 つのテーブルを更新する代わりに、2 つの異なる場所で情報を更新する必要があります。

400 万人のユーザーがいて、何千もの同時アクセスがある場合、タイミングによる小さな不一致が目立ち、ユーザーからの苦情が発生する可能性があります。苦情が増えている理由についての CEO からの電話は、おそらくあなたが対処したいものではありません。

別の方法は、UserRewards(UserId, BatchId, RewardsId) にインデックスを作成することです。おそらく、各フィールドは数バイトであるため、3,000 万のレコードは 8 GB のメモリに簡単に収まるはずです (SQL Server にほぼすべてのメモリが割り当てられていることを確認してください!)。必要なクエリは、UserRewards テーブルをメモリに読み込まなくても、このインデックスによって厳密に満たすことができます。したがって、インデックスのみをキャッシュする必要があります。そして、このクエリ用に最適化されます。

すべてを遅らせる原因の 1 つは、報酬を割り当てる頻度です。これらが読み取り率の 10% でも割り当てられている場合、挿入/更新によって読み取りがブロックされる可能性があります。この問題を回避するには、READ_NOLOCK を使用してクエリを実行する必要があります。また、読み取りとの競合を避けるために、ロックがレコードまたはページ レベルで発生していることを確認する必要があります。

于 2012-11-30T21:31:20.477 に答える
0

遅すぎるかもしれませんが、uniqueidentifiers をキーとして使用すると、(int をキーとして使用する場合と比較して) ストレージ スペースが 4 倍になるだけでなく、クエリが桁違いに遅くなります。避ける!!!

于 2013-01-20T20:35:03.647 に答える