人気が高まっているモバイル 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 番目のオプションが最適であると考えています。私たちはその費用を支払う用意があります。
私たちのために働くかもしれない他のアプローチはありますか?上記で概説したアプローチに、私たちの決定に影響を与える可能性のある追加の長所や短所はありますか?