0

人気が高まっているモバイル Web サイトに取り組んでおり、これによりいくつかの主要なデータベース テーブルが増加しています。これらのテーブルにアクセスする際にパフォーマンスの問題が発生し始めています。私たちはデータベースの専門家ではありません (また、この段階で誰かを雇うお金もありません)、パフォーマンスの問題の原因を理解するのに苦労しています。私たちのテーブルはそれほど大きくないので、SQL Server はそれらをうまく処理できるはずであり、クエリの最適化に関して知っていることはすべて実行しました。したがって、(疑似)テーブル構造は次のとおりです。

[user] (approx. 40,000 rows, 37 cols):

id               INT (pk)
content_group_id INT (fk)
[username]       VARCHAR(20)
...

[content_group] (approx. 200,000 rows, 5 cols):

id    INT (pk)
title VARCHAR(20)
...

[content] (approx. 1,000,000 rows, 12 cols):

id                  INT (pk)
content_group_id    INT (fk)
content_type_id     INT (fk)
content_sub_type_id INT (fk)
...

[content_type] (2 rows, 3 cols)

id INT (pk)
...

[content_sub_type] (8 rows, 3 cols)
id              INT (pk)
content_type_id INT (fk)
...

これらの行数は大幅に増加すると予想されます (特に、user、content_group、および content テーブル)。はい、ユーザー テーブルにはかなりの数の列があります。他のテーブルに移動できるいくつかの列を特定しました。また、影響を受けるテーブルに適用した一連のインデックスも役に立ちました。

大きなパフォーマンスの問題は、ユーザーの検索に使用しているストアド プロシージャです (これには、content_group_id フィールドでのコンテンツ テーブルへの結合が含まれます)。WHEREさまざまなアプローチを使用してand句を変更しようとしましたがAND、できる限り良いものになったと思いますが、それでもまだ遅すぎます。

私たちが試したもう 1 つのことは、ユーザー テーブルとコンテンツ テーブルにインデックス付きビューを配置することでした。これを行ってもパフォーマンスが大幅に向上することはなかったので、ビュー レイヤーを使用することで複雑さが増すため、このアイデアを放棄しました。

それで、私たちの選択肢は何ですか?いくつか考えられますが、すべて長所と短所があります。

テーブル構造の非正規化

ユーザー テーブルとコンテンツ テーブルの間に複数の直接外部キー制約を追加します。これにより、コンテンツ サブタイプごとに異なる外部キーがコンテンツ テーブルに存在します。

長所:

  • 主キーを使用すると、コンテンツ テーブルへの結合がより最適になります。

短所:

  • 既存のストアド プロシージャと Web サイト コードに多くの変更が加えられます。
  • 最大 8 つの追加の外部キー (より現実的には 2 つだけを使用します) を維持することは、現在の単一のキーほど簡単ではありません。

テーブル構造のさらなる非正規化

必要なフィールドをコンテンツ テーブルからユーザー テーブルに直接複製するだけです。

長所:

  • コンテンツ テーブルへの結合が不要になり、SQL の作業が大幅に削減されます。

短所

  • 上記と同じ: ユーザー テーブルで維持する追加フ​​ィールド、SQL および Web サイト コードの変更。

中間層のインデックス レイヤーを作成する

Lucene.NET などを使用して、データベースの上にインデックス レイヤーを配置します。これにより、理論的にはすべての検索のパフォーマンスが向上し、同時にサーバーの負荷が軽減されます。

長所:

  • これは良い長期的な解決策です。Lucene は、検索エンジンのパフォーマンスを向上させるために存在します。

短所:

  • 短期的にははるかに大きな開発コストが発生します。この問題を早急に解決する必要があります。

以上が私たちが思いついたことであり、現段階では 2 番目のオプションが最適であると考えています。私たちはその費用を支払う用意があります。

私たちのために働くかもしれない他のアプローチはありますか?上記で概説したアプローチに、私たちの決定に影響を与える可能性のある追加の長所や短所はありますか?

4

1 に答える 1

1

content_sub_type_id を使用してコンテンツ テーブルから非クラスター化インデックス シーク。これに続いて、コンテンツ テーブルに対する content_group_id のハッシュ マッチが行われます。

contentこの説明は、負荷の高いクエリが次のフィールドに基づいてテーブルをフィルタリングしていることを示していますcontent_type

select ...
from content c
join content_type ct on c.content_type_id = ct.id
where ct.<field> = <value>;

この表の設計と、その結果として見られる問題は、実際には非常に一般的です。この問題は、主にルックアップ テーブルの選択性が非常に低いために発生します ( content_type2 つの行があるため、コンテンツの content_type_id の選択性はおそらく 50% と非常に大きくなります)。試すことができる解決策がいくつかあります。

content1) content_type_id を先頭キーとしてクラスター化インデックスでテーブルを編成します。これにより、結合で範囲スキャンを実行できるようになり、射影の完全性のためのキー/ブックマーク ルックアップも回避できます。クラスター化インデックスの変更は、他のクエリに影響を与えるため、慎重にテストする必要があります。主キー oncontentは、明らかに非クラスター化制約で強制する必要があります。

2) 値を事前に読み取り、content_type_idと の間の結合を使用せずにクエリを作成しcontentますcontent_type

select ...
from content c
where c.content_type_id = @contentTypeId;

これは、 content_type_id の選択性が高い場合にのみ機能します (それぞれの行数が少ない多くの異なる値)。これはあなたのケースではないと思います (おそらく、コンテンツ タイプが非常に少なく、それぞれに多くのエントリがあります)。

3) content_Type を content に非正規化します。あなたは非正規化について言及していますが、コンテンツをユーザーに非正規化するというあなたの提案は、私にはほとんど意味がありません。テーブルを削除content_typeし、content_type フィールドをcontentテーブル自体に取り込み、すべての非正規化の問題に対処します。

4) マテリアライズド ビューで事前結合します。あなたはすでにそれを試したと言いますが、正しい具体化されたビューを試したとは思えません。また、Enterprise Edition のみがマテリアライズド ビュー インデックスを自動的に使用し、他のすべてのエディションではNOEXPANDヒントが必要であることも理解する必要があります。

create view vwContentType 
with schemabinding
as 
select content_type_id, content_id
from dbo.content c
join dbo.content_type_id ct on c.content_type_id = ct.content_type_id;

create unique clustered index cdxContentType on vwContentType (content_type_id, content_id);

select ...
from content c
join vwContentType ct with (noexpand)
on ct.content_id = c.content_id
where ct.content_type_id = @contentTypeId;

解決策 2)、3)、および 4) は、ほとんど学術的なものです。content_type_id の選択性が非常に低いことを考えると、永続的な可能性がある唯一の解決策は、それを のクラスター化インデックスの主要キーにすることですcontent。分析を に拡張しませんでしたcontent_Sub_typeが、8 行しかないので、まったく同じ問題があり、クラスター化されたインデックス (おそらく 2 番目の先行キーとして) にもプッシュする必要があると確信しています。

于 2011-10-10T17:58:48.057 に答える