3

私は人事システムに取り組んでおり、各採用担当者は候補者のプロファイルに対して限られたビューしか持たないため、ユーザーのプロファイルに関するすべてのビューの追跡記録を保持する必要があります。私の主な関心事は、私のアプローチのスケーラビリティです。これは次のとおりです。現在、表示された候補者のIDと候補者を表示したリクルーターのIDの2つの列を持つテーブルを作成しました。各ビューは、1回だけカウントされます。同じ候補が再び表示されますが、レコードは挿入されません。

データベース内の採用担当者と候補者の数に基づいて、テーブルは非常に速く成長し、最悪の場合、UIに候補者の数を表示する必要があるため、リクエストごとにテーブルをクエリする必要があると言っても過言ではありません。採用担当者が閲覧しました。スケーラビリティを考慮すると、どちらが最善のアプローチですか?


ケースについてもう少し説明します。私たちには会社があり、すべての会社には多くのリクルーターがいます。

ViewsAssigner_Identifierテーブル

  • Id:int PK
  • Company_Id:int FKNON-CLUSTERED
  • Views_Assigned:intNON-CLUSTERED
  • 日付:クラスター化されていない日付

CandidateViewCountsテーブル

  • Id:int PK
  • Recruiter_id:int FK NON-CLUSTERED?
  • Candidate_id:int FK NON-CLUSTERED?
  • ViewsAssigner_Identifier_Id:int FK NON-CLUSTERED?
  • DateViewed:クラスター化されていない日付

[ViewsAssigner_Identifier_id]によってすべての[Candidate_id]の選択を照会します

同じ会社のすべてのリクルーターが同じ[Views_Assigned]を会社に使用したため、リクルーターではなく会社で検索したいと思います。つまり、候補を表示する最初のRecuiterは「CandidateViewCounts」テーブルに格納され、同じ候補を表示する後続のRecuiterは格納されません。

結果: [ViewsAssigner_Identifier_id]によってすべての[Candidate_Id]のリストを取得する必要があります。そうすれば、これらすべての候補IDを合計できます。

クエリの例:

SELECT [Candidate_Id]FROM[dbo]。[CandidateViewCounts]WHERE[ViewsAssigner_Identifier_id] = 1

何かお勧めはありますか?

4

2 に答える 2

3

各採用担当者が各候補者を 1 回表示すると考える場合、最大 60,000 * 2,000,000 行について話していることになります。これは大きな数ですが、それほど幅の広い行ではありません。ErikE が説明したように、各ページで多くの行を取得できるため、テーブル スキャンの合計 I/O は、思ったほど悪くはありません。

とはいえ、メンテナンス上の理由から、CandidateID で検索しない限り、このテーブルを RecruiterID で分割することをお勧めします。たとえば、パーティション スキームには、1 から 2000 までの RecruiterID 用の 1 つのパーティション、2001 -> 4000 用の 1 つのパーティションなどを含めることができます。このようにして、パーティションごとの行数を最大化し、それに応じてファイル スペースを計画できます (各パーティションを配置できます)。 I/O を分離する独自のファイル グループ)。

もう 1 つのポイントは次のとおりです。「この候補者のビュー数 (どのリクルーターかは関係ありません)」などのクエリを実行しようとしている場合。または「この採用担当者は何人の候補者を閲覧しましたか (どの候補者かは気にしません)」次に、インデックス付きビューを検討できます。例えば

CREATE VIEW dbo.RecruiterViewCounts
WITH SCHEMABINDING
AS
  SELECT RecruiterID, COUNT_BIG(*)
    FROM dbo.tablename;
GO
CREATE UNIQUE CLUSTERED INDEX pk_rvc ON dbo.RecruiterViewCounts(RecruiterID);
GO

CREATE VIEW dbo.CandidateViewCounts
WITH SCHEMABINDING
AS
  SELECT CandidateID, COUNT_BIG(*)
    FROM dbo.tablename;
GO
CREATE UNIQUE CLUSTERED INDEX pk_cvc ON dbo.CandidateViewCounts(CandidateID);
GO

現在、これらのクラスター化されたインデックスは維持するのに費用がかかるため、それらに対して書き込みワークロードをテストする必要があります。しかし、これらの 2 つのクエリは非常に高速で、大規模なテーブルをシークする必要がなく、非常に忙しい採用担当者や非常に人気のある候補者のために複数のページを読み取る可能性があります。

于 2013-01-15T22:40:38.720 に答える
1

テーブルがクラスター化されているRecruiterID場合、シークは非常に高速になり、私の意見ではパフォーマンスの問題はまったくありません。

あなたが説明したような狭いテーブルでは、1人のリクルーターについて表示されたプロファイルを見つけるには、99%以上の時間で1回の読み取りが必要です。(最小のページ分割でfillfactor = 80と仮定し、2つのint列を仮定した行幅= 16バイト+オーバーヘッド、それを20バイトと呼びます;ページあたり8040バイト程度;リクルーターあたり平均2.5行で4ビューを取得すると=データあたり128リクルーターをボールパークページ)。テーブル内の行の総数は、クラスター化インデックスを検索できるため、関係ありません。ええ、それは木を横断する必要がありますが、それでも非常に高速になります。ビューが候補ごとに1回カウントされる必要がある限り、これ以上の方法はありません。単に合計ビューの場合は、代わりにカウントを維持できます。

心配することはあまりないと思います。システムが毎秒数万のリクエストに成長する可能性があり、ある時点で訪問するリクルーターが偶然にシーケンシャルIDを割り当てられていない限り、アクティビティのホットスポットが制限されることが懸念される場合それら、あなたは大丈夫になります。

ここでの大きな原則は、テーブルを上から下にスキャンする必要があるものはすべて避けたいということです。RecruiterID常にまたはで検索する限り、これを回避できますRecruiterID, CandidateID。一人で検索したい瞬間CandidateID、追加のインデックスがないと困ります。非クラスター化インデックスをに追加するCandidateIDと、テーブルに必要なスペースが2倍になります(クラスター化の場合は半分、非クラスター化の場合は半分)が、それは大したことではありません。CandidateID非クラスター化インデックスがクエリを適切にカバーし、ブックマークの検索が不要になるため、検索も同様に高速になります。

アップデート

これは、質問の更新で提供した実質的に新しい情報への回答です。

まず、CandidateViewCountsテーブルの名前が間違っています。のようなものCandidateFirstViewedByRecruiterAtCompanyです。それはあなたが持っている質問に間接的にしか答えることができません。それは採用担当者ではなく会社に関するものです。したがって、私の意見では、あなたが説明しているシナリオは実際にCompanyCandidateViewedテーブルを必要とします。

CompanyID int FK
CandidateID int FK
PRIMARY KEY CLUSTERED (CompanyID, CandidateID)

候補者を見たリクルーターのCompanyIDとCandidateIDを保存します。単純!今でも私の元の答えはあなたのために機能します、単にと交換RecruiterIDしてCompanyIDください。

どのリクルーターがどの候補者を閲覧したかを本当に追跡したい場合は、RecruiterCandidateViewedテーブルに記録します(そして、すべてのリクルーター->候補者ビューを保存します)。これは、後でまたはデータウェアハウスで照会できます。ただし、リアルタイムのOLTPのニーズは、上記の表で満たされます。

また、ID列を必要としないテーブルに配置している可能性があることにも言及したいと思います。列が別のテーブルでFKとして使用される場合を除いて、ID列は避ける必要があります(非正規化を防ぐために適切なデータモデリングでFKで複合キーを使用する必要がある場合があるため、常にそうとは限りません)。たとえば、あなたのViewsAssigner_Identifierテーブルには助けが必要なようです(もちろん、ここにすべての情報があるわけではなく、ベースから外れている可能性があります)。Companyとがそのテーブルで最も重要なものである場合はDate、それらをクラスター化されたPKにまとめ、可能な場合はID列を削除します。

于 2013-01-15T22:22:20.437 に答える