Skip to main content
OutSystems

パフォーマンスのベストプラクティス - データモデル

以下のベストプラクティスは、アプリケーションのデータ層を対象にしています。データ層はアプリケーションのパフォーマンスにとって極めて重要です。開発フェーズの終盤になってベストプラクティスを適用するとコストが高くなるため、設計フェーズでパフォーマンスをおろそかにしないようにします。 

エンティティのインデックスを作成する

説明

よく使用するアトリビュートのインデックスを作成し、全体的なクエリ速度を向上させます。ただし、インデックスを使用すると挿入や更新の時間が長くなることに注意してください。

ソリューション 

低速なクエリのクエリ条件や結合式で使用されているアトリビュートをすべて特定します。これらが最適なインデックス作成の候補です。

クエリの全体的なパフォーマンスの向上は、アトリビュートのデータ型とインデックスの有無によって大きく異なります。日付や小さいテキストなど、特に少数のアトリビュート値でインデックスを作成するとパフォーマンスが大幅に向上します。Boolean型のアトリビュートにも有効です。これは、常にクエリ自体とエンティティ上のデータの量に依存します。

重要事項

大きいテーブルに対するクエリに時間がかかりすぎる場合、データベースインデックスを使用すると、データベースエンジンがクエリ対象値についてテーブルデータページを検索しなくて済むため、そのテーブル内のデータへのアクセスを高速化できます。特定の順序で整理されたページの小さなサブセット(インデックスページ)を使用し、ソートアルゴリズムによって検索機能を向上します。

特定のエンティティでクエリによく使用するすべてのアトリビュートに対するインデックスを作成する必要があります。また、場合によっては同じテーブル内でクエリによく使用するアトリビュートグループに対してもインデックスを作成します。しかし、テーブル内のインデックスの数が多いほど、これらのインデックスが自動的に更新されるために挿入や更新などのオペレーションに時間がかかり、これらのオペレーションのパフォーマンスが低下してしまうことに留意してください。select文やinsert/update文とインデックス数の最適な妥協点を特定することがポイントです。

注意事項

インデックスでは列の順序が重要です。そのため、クエリ内では常に同じ順序を使用するようにします。複数の列を使用してフィルタリングするクエリの場合、複合インデックスを作成できます。

大きいテキストデータやバイナリデータを分離する

説明

2,000文字を超えるText型のアトリビュートは避けます。Binary Data型のアトリビュートと大きいテキストアトリビュートをそれぞれ別のエンティティに保存します。

ソリューション

Text型のアトリビュートの長さを最小限の値に減らします。長さが2,000を超えるText型のアトリビュートは避けます。Service StudioのText型のアトリビュートの長さが2,000未満の場合、SQL ServerではVarChar列として作成されます。これより長い場合はText列として作成されます。

Binary Data型のアトリビュートを別のエンティティに分離します。

重要事項

大きいText型のアトリビュートやBinary Data型のアトリビュートを含むエンティティの更新は非常に低速です。2,000文字を超えるText型のアトリビュートがある場合、データベースではBinary Data型にマッピングされます。通常、Binary Data型は単純なデータ型に比べて変更/更新に時間がかかる傾向があります。また、Binary Data型ではデータページを移動する必要があるため、Binary Data型のレコードの更新は単純なデータ型のレコードの更新より時間がかかります。そのため、頻繁に変更されるエンティティにBinary Data型を含めるのは避けるべきです。どうしても避けられない場合は、それぞれのエンティティに分離します。

注意事項 

データモデルの設計時に、値をグループ化して集約すると高レベルの検索/レポートを取得するためのリクエスト/トランザクションの量が少なくなります。

大きいExcelファイルのパフォーマンスに注意する

説明

大きいExcelファイルを処理する場合、エンティティのデータを記録し、タイマーを使用してバックグラウンドでデータを処理することを検討します。

ソリューション

アップロードする行数が一定でない場合、アプリケーションが65,536レコードの読み込みに対応していることを確認する必要があります。これはExcelで処理できる最大レコード数です(注記: MS Office/Excel 2007では100万行が限度です)。また、最悪の場合、Excelが2分を超える読み込みを行わず、テーブルが大きくなるにつれてテーブル挿入が次第に遅くなっていくことに留意します。

最も安全な方法は、一時テーブルを使用してそこにExcelのバイナリ情報をそのまま挿入し、タイマーを起動して非同期に処理することです。

重要事項

データ処理とデータアップロードを分離することにより、リクエストタイムアウトの制限を回避します。また、バックグラウンドで一括処理ジョブとして処理が行われるため、分離されたサーバー上で実行する、再試行できるようにする、エラー処理を実行する、1行ごとにコミットするなどの他のベストプラクティスに準拠できます。

注意事項

アプリケーションのブートストラップ用のExcelファイルについては、上記のプロセスは不要です。 

エンティティで削除規則制約を使用する

説明

可能な限り、参照アトリビュートのDelete RuleをDeleteではなくIgnoreに設定するようにします。

これは、注意を要する高度なシナリオです。データが不整合になり、アプリケーションで深刻な問題が発生する場合があります。

ソリューション

このベストプラクティスは、データがデータベースから効率的に削除されるアプリケーションで、他のエンティティが依存するエンティティに対してこのことが行われる場合に適用されます。以下に示す3つのシナリオのいずれかを選択できます。

  1. Protect規則を使用する。この場合、アプリケーションは最初に子エンティティからすべてのレコードを削除する(またはデータベースがエラーを返す)必要があります。その後、親エンティティのレコードを削除する際に、データベースは子エンティティ内にレコードがあるかどうかを確認する必要があります(これは不要であるか、またはエラーを返します)。これはパフォーマンス面ではよい方法とはいえません。
  2. Delete規則を使用する。この場合、すべての制御を(ビジネス知識を持たない)データベースが行い、すでに削除されたものも削除しようとすることがあります。
  3. Ignore規則を使用する。アプリケーションが適切に動作していない場合にデータの不整合が発生する可能性がありますが、非常にパフォーマンスに優れた方法です。この方法を使用する場合、データベースのハウスキーピング戦略を定め、インデックスがないデータがないようにすることが基本になります。

重要事項

エンティティの参照アトリビュートのDelete RuleのProtectオプションとDeleteオプションは、参照データモデルで複数のアクションをトリガーします。このとき、データベースのオーバーヘッドが発生し、レコードの削除にかかる時間が長くなります。これは、エンティティレコードの削除規則により、外部キー制約でそのレコードにリンクしている他のテーブルのすべてのレコードに対してselect文またはdelete文が実行されるために発生します。複雑なデータモデルではIgnore規則を使用するのが最適です。これらのdelete文は実行されませんが、削除する他の参照エンティティ内のレコードを手動で確認する必要があるためです。

注意事項

このベストプラクティスはデータの不整合を発生させることがあるため、多くの開発者が疑念を抱き、Protect規則を使用しています。しかし実際には、Ignore規則では削除が必要なものをアプリケーションがすべて削除していない場合にデータの不整合が発生するのに対し、Protect規則ではデータベースエラーが発生します。これは検出しやすいものの、エンドユーザーエクスペリエンス上どちらも好ましくない結果である点に変わりはありません。開発段階やテスト段階で制約を一時的にProtectに設定すると、開発エラーに対する対策になる場合があります。データの不整合のリスクを最小限に抑えるためのプラクティスとして、開発やテストが完了次第、制約をIgnoreに設定し、削除が配置されている場所にリマインダーを追加し、また、テスト時にProtectに戻す必要がある規則を示します。 

古いデータを別のエンティティにアーカイブする

説明

次の場合、別のエンティティを使用して古いデータをアーカイブすることを検討する必要があります。(a)ロギングまたは法律上の理由で古いデータを保持する必要があるが、アプリケーション内のどこからもアクセスできない場合、(b)増大率の高いテーブルで、頻繁に使用されるデータの割合が少なく、その他のデータはほとんどアクセスされずアーカイブとしてのみ使用される場合。また、アーカイブデータを表示する別の画面を作成することや、あまり使用されないクエリで両方のテーブルからデータを参照できるユニオンまたはビューを使用することを検討します。

ソリューション

定期的に手動で実行するデータベーススクリプトによってテーブルから古いレコードを削除するをプロセスは、誰も覚えていないという事態を招くため推奨されません。こういった業務は自動化し、アプリケーションに含める必要があります。注文やオペレーションなどの履歴データを含むテーブルがある場合は、アーカイブテーブルを用意し、日次のタイマーを使用して一定の時期より古いレコードを主テーブルからアーカイブテーブルへコピーするとよいでしょう。増大率の高いテーブルで、重要なデータの割合が少なく、その他は単なるアーカイブとなっている、ほとんどアクセスされないデータについても同様です。

重要事項

古いデータはテーブルの重荷であり、テーブルデータに対して実行されるあらゆるオペレーションの速度を低下させます。多くの場合、古いデータが使用されるのは1%程度にすぎません。

注意事項

古いデータを別のエンティティにアーカイブするタイミングは慎重に検討する必要があります。アーカイブが早すぎるとアーカイブされたデータへのアクセスが多くなり、パフォーマンスに悪影響を及ぼすことがあります。