Skip to main content
OutSystems

パフォーマンスのベストプラクティス - ロジック

このトピックの内容は、パフォーマンスを常に意識した高水準のコーディングを行う開発者の能力に大きく依存するものであり、細心の注意が必要です。一部のタスクは、経験則として使用する必要があります(これらはすべての種類のアプリケーションに適用されます)。

Service Centerのレポートを使用する

説明

Service Centerのレポートを使用してパフォーマンス上の問題を見つけ、最適化プロセスの指針にします。

ソリューション

Service Centerのレポートを使用してアプリケーションのパフォーマンスを確認し、調整します。

重要事項

アプリケーションのパフォーマンスに関するボトルネックがある場合、Web画面、WAP画面、Webサービス、タイマーによる低速なアプリケーションアクセスと、拡張機能やWebサービスによる低速なデータベースクエリまたは連携の全体像を、Service Centerの[Analytics]セクションで確認できます。これにより、システムとアプリケーションのボトルネックをすばやく特定し、これらの項目を集中的に分析できるため、トラブルシューティングにかかる時間を短縮できます。

注意事項

通常、これがあらゆる最適化ニーズの開始点になります。

タイマーおよびバッチジョブの長期実行を避ける

説明

バックグラウンド処理をすべて連続して行わないようにします。コントロールテーブルを使用してデータをグループに分けて処理し、実行終了時に自身を再スケジュール設定します。

ソリューション

タイマーを長時間実行しないようにします。タイマーの実行は長くても20分間にし、タイマーを再スケジュール設定してすぐに再開し、残りのタスクを続行します。これを実現するには、タイマーロジック内に明示的なタイムアウトを追加します。このロジックでは、タイムアウトに達したときに必要なアクションを行って現在の処理を適切に終了し、処理の現在のステータスを保存して処理が再開したときに停止時点からの処理をシームレスに続行できるようにします。実行の最後に、タイマー自体に対するウェイクタイマーアクションでタイマーを終了します。

重要事項

シナリオ: タイマーは時間がかかりすぎるため、ワーカープロセスのリサイクルによって中断されます。エラーやオペレーション次第では、外部システムと通信している場合にこの問題によってデータの不整合が発生することがあります。タイマーがプラットフォームのタイマーのタイムアウトしきい値を超えると、同一データがエンドレスで再処理されることがあります。タイマーを短時間実行した後に自動的に再起動させることにより、(a)ワーカープロセスのリサイクルによるタイマーの中断、(b)データの不整合の発生、(c)同一データのエンドレスな再処理の可能性が減少します。様々なタイマーを組み込み、ジョブがバランスよく処理されるようにします。

注意事項

長時間のタイマーとバッチジョブに関する方針として、データに影響を及ぼすことなくタイマーを停止・再開できるようにするため、これらを定義するときにチェックポイントを定義することも推奨しています。これらのチェックポイントで、タイマーで何らかの問題が発生したときに処理された情報がすべてロールバックされないようにするため、部分コミットを実行することを検討します。

画面のPreparationを簡素化する

説明

画面の読み込み速度を向上させるため、画面のPreparationアクションを簡素化します。

ソリューション

画面のPreparationをシンプルなものにします(大きく複雑なPreparationにすると画面の表示が遅くなることがあります)。Preparationに次のいずれかの状況があるかどうかを確認します。

  1. クエリ結果の事前処理。表示オペレーションでは、テーブルへの新しいフィールドの追加やデータの処理を避けます。代わりに、書き込みオペレーションで行います。
  2. for-each内でのクエリ。多くの場合、複雑なクエリを1回だけ実行して必要な情報を取得するほうが、単純なクエリをfor-eachループ内で実行するよりも適切です(「クエリ数を最小限にする」のトピックをご覧ください)。
  3. すべてのページで実行される複雑な権限検証。セッション開始時に一度実行して、セッションまたはデータベースに保存できるかどうかを確認します。

重要事項

ページの読み込みに時間がかかると、ユーザーエクスペリエンスに大きな影響を及ぼします。ページの描画にかかる時間を短くする、つまり、可能な限りデータベースの読み取りオペレーションを最小限にする必要があります。また、描画時間を短縮するため、データベースの書き込みオペレーションを(本当に必要でない限り)画面のPreparation内では実行しないようにします。

サイトプロパティを使用する

説明

頻繁に変更されるロジック変数としてサイトプロパティを使用することは避けます。

ソリューション

サイトプロパティは変数ではなく定数とする必要があります。各画面または各セッションでサイトプロパティを変更する場合、データベーステーブルを使用して、サイトプロパティ情報とその管理のための対応するバックオフィス機能を保存することを検討します。

重要事項

サイトプロパティを変更すると、すぐにデータベースが変更されるため時間がかかります。アプリケーションがすぐに新しい値を認識するためには、TenantInvalidateCacheオペレーションを発行する必要があり、このときアプリケーションのキャッシュの再読み込みが行われます。これが続けて行われると、アプリケーションとデータベースのオーバーヘッドが増加します。

注意事項

負荷が高いときにサイトプロパティを同時に変更すると、「transaction has been chosen as deadlock victim(トランザクションがデッドロックになりました)」などのメッセージが表示されることがあります。

セッション変数をうまく使用する

説明

セッションに配置する情報はできるだけ少なくし、大きいレコードやレコードリストは特に避けます。

ソリューション

大きいセッション変数を使用することは避けます。アプリケーションの同時ユーザー数が増加すると、大きいセッション変数の使用による影響が大きくなります。(フィルタの保存などで)セッション変数を使用する代わりに、ユーザーIDを主キーとしてデータベーステーブルに保存します。違いは、リクエストごとに取得するのではなく、データが使用されているページでのみデータを取得する点です。

重要事項

各Webリクエストでは、現在のセッションのコンテキストが読み込まれます。セッション変数が大きいテキスト文字列の場合、各リクエストでセッションデータモデルからセッション変数を取得するのに時間がかかるため、セッションデータモデルで競合が発生し、他のアプリケーションユーザーへの影響が拡大します。Ajaxを使用するときはリクエスト数が増えるため、これがさらに重要になります。

注意事項

セッションがないサービスがある場合は、セッションをすべて削除する(セッションをInPRocに設定する)ことでパフォーマンスをうまく向上できます。

分離された単純なクエリの使用を避ける

説明

単純なクエリを実行するアクションを作成しないようにします。クエリがアクション内で分離されている場合、取得されるフィールド数をプラットフォームで最適化できません。

ソリューション

コンパイラオプティマイザは、使用するフィールドを自動的に検出します。しかし、出力がエンティティまたはレコードリストであるアクションを呼び出す場合、DBからエンティティ(レコードリストの場合は複数のエンティティ)がすべて取得します。

重要事項

これは、アクションがエンティティ/レコードリストのすべてのフィールドを読み取らない場合も該当します。これにより、不要なデータベースの過負荷やメモリの使用が発生します。

注意事項

これにより、コードの再利用ができなくなります。そのため、場合によっては(特に出力が大きくない場合は)類似したクエリを多く使用する代わりに、分離されたクエリを使用するほうが適切です。

PreparationのIfブランチ内でクエリを使用することは避ける

説明

ビューステートに余計なクエリデータが送られないようにするため、Preparationで条件付きクエリを使用することは避けます。

ソリューション

更新画面を使用する場合は、条件付きクエリ(Ifブランチ内のクエリ)に注意します。これを避けるため、ローカル画面変数を宣言し、それをクエリから、空のレコードリストとともにPreparationの開始時に割り当てます。

重要事項

Preparation内のIfブランチ内のみでクエリが実行され、そのブランチ外(テーブルレコード内など)で使用された場合、そのデータはビューステート内で常に必要になります。これは、クエリが頻繁に実行されないためです。そのため、ページのビューステートのサイズが増加します。

注意事項

これはエンドノードで終了する(画面の更新が発生する)送信アクションを使用する場合にのみ発生します。Ajaxアクションやターゲットの場合、適用されません。