データベースの設計とパフォーマンス (SQL Server Compact)

SQL Server Compact 4.0 アプリケーションのパフォーマンスは、SQL Server のデータベースとパブリケーションを正しく設計することで大幅に向上できます。以下のセクションでは、パフォーマンスの向上に使用できる手法の概要を説明します。

データベースの非正規化の使用

正規化されたデータベースは、データが機能上の依存関係を持たず、データベースの更新を容易かつ効率的に行えるようになっています。ただし、データベースに対してクエリを実行する際、情報を結合するために多くのテーブルを結合することが必要になる場合があります。結合テーブルの数が増加するにつれて、クエリの実行時間は長くなります。そのため、正規化されたデータベースが最善の選択肢とはいえない場合があります。適度に非正規化したデータベースを使用すると、結合するテーブルの数を減らすことができます。その際の更新処理はそれほど複雑ではありません。これが適切な代替案になる場合が数多くあります。

注意

通常、多数のクエリで 5 個または 6 個以上のテーブルを結合する必要がある場合は、非正規化を検討してください。

データベースの非正規化には他の種類もあります。たとえば、データベースに Orders および Order Details という 2 個のテーブルがあるとします。Orders テーブルには、顧客の注文に関する情報が含まれています。各注文の個別の商品は Order Details テーブルに含まれています。各注文の合計金額をクエリしてみましょう。まず、各商品の金額を特定する必要があります (個数 x 単価 – 適用可能な割引額で算出できます)。その後、注文ごとに金額をまとめる必要があります。以下に、使用するクエリを示します。

SELECT "Order ID", SUM("Unit Price" * Quantity * (1.0 - Discount))

AS Total FROM "Order Details"

GROUP BY "Order ID"

Order ID Total

----------------------------------------

10000 108

10001 1363.15000915527

10002 731.800003051758

10003 498.180023193359

10004 3194.19999694824

10005 173.400009155273

10006 87.2000007629395

10007 1405

10008 1171

10009 1530

10010 470

... ...

(1078 rows affected)

このクエリの計算は慎重に行う必要があります。大口の注文では、クエリの実行に長時間かかります。この代替策として、注文が行われた時点で注文の金額を計算し、Orders テーブル内の列にその金額を格納しておくことができます。このアプローチを使用する場合、計算前の列に対してのみクエリを実行し、必要な情報を返す必要があります。これを行うには次のようなステートメントを使用します。

SELECT "Order ID", "Order Total" AS Total FROM Orders

計算前の列を作成することにより、クエリ時間を大幅に縮小することができますが、このアプローチではテーブル内に別の列を保持することが必要になります。

可変長列または固定長列の選択

テーブルの設計時には、可変長列と固定長列の用途の違いを理解しておくと役立ちます。可変長列は、実際の値を格納するために必要なものだけを使用するので、データベース サイズが減少します。固定長列は、実際の値が空の場合でも、スキーマによって定義された最大領域を常に格納します。可変長列の欠点は、演算によっては固定長列での演算ほど効率的ではないものがあることです。たとえば、可変長列のサイズが最初は小さく、UPDATE により大幅にサイズが増加すると、レコードの再配置が必要になる場合があります。さらに、その後の更新処理により、データ ページが長期にわたってより多くの断片に分割されます。そのため、データのサイズがほとんど変わらない場合と更新の実行頻度が高い場合は、固定長列を使用することをお勧めします。

サイズが小さい行の作成

ページに保持できる行の数は、各行の最適化方法によって異なります。行のサイズが小さいほど、ページにはより多くの行を保持できます。そのため、最適化した行を持つテーブルで 1 つのディスク操作を行うと、複数の行を取得でき、操作がより効率的になります。さらに、複数の行がストレージ エンジンのキャッシュに含まれるので、ヒット率が高くなる可能性があります。また、行を最適化すると、データ ページ上の不要な領域が削除されます。サイズが大きな行では、不要な領域がよく生じます。

これに関する極端な例について考えて見ましょう。レコードのサイズがデータ ページの半分より若干大きい場合、各データ ページの領域の約半分は不要になります。データベース設計者によっては、広大なテーブルを設計し、メインフレームのデータベース スキーマをデバイスに移植する場合があります。これは効率的な設計とはいえません。考えられるアプローチの 1 つは、最も重要なテーブルを分割することです。ほとんど変化しない値と頻繁に変化する値を持つ列がいくつか含まれているテーブルがあるとします。その場合、テーブルを 2 つに分割するのが合理的です。1 つは頻繁に参照される列を含むテーブルで、もう 1 つは変化しない列を含むテーブルです。2 つのテーブルを作成することにより、行のサイズが小さくなるという利点があります。欠点としては、情報を組み合わせるための結合処理が必要になります。

サイズが小さいキーの使用

インデックスは、作成先のテーブルの順序付けされたサブセットです。インデックスにより、高速な範囲照合と並べ替え順序が許可されます。インデックス キーが小さいほど、使用する領域が少なくなり、大きなキーよりも効率的になります。主キーは他のテーブル内の外部キーとして頻繁に参照されるので、主キーを最適化するのは特に効果的な方策です。元から最適化されている主キーがない場合は、整数型として実装されている ID 列を代わりに使用できます。

1 つまたは少数のキー列しか含まないインデックスは、狭いインデックスと呼ばれます。多くのキー列を持つインデックスは、広いインデックスと呼ばれます。広いインデックスは、サイズの大きいキーに関連付けられていることがよくあります。この極端な例は、テーブル内の各列がインデックスに含まれる場合です。このようなインデックスを作成すると、元のテーブルの複製が効率的に作成されますが、これは、データベースのサイズとクエリのパフォーマンスの点から見ると効率的ではありません。

関連項目

概念

クエリ パフォーマンスのチューニング (SQL Server Compact)

その他の技術情報

パフォーマンスの向上 (SQL Server Compact)