アンチ パターンのクエリ
Dataverse 用に最適化されたクエリを作成することは、アプリケーションが高速で応答性が高く、信頼性の高いエクスペリエンスを提供するために不可欠です。 標準テーブル用のクエリを作成する際に避けるべきパターンについて、RetrieveMultiple
メッセージ、または QueryBase クラスを継承するパラメーターを持つメッセージを使用して解説します。
OData を使用してレコードのコレクションに対して GET
リクエストを送信する場合にも、このガイダンスが適用されます。
ヒント
ここでのガイダンスは、エラスティック テーブル や Dataverse 検索を使用する場合には適用されない場合があります。
選択した列の数を最小限にする
クエリに必要のない列を含めないでください。 すべての列を返すクエリや多数の列を含むクエリでは、データセットのサイズやクエリの複雑さにより、パフォーマンスの問題が発生する可能性があります。
選択した論理列の数を最小限にする
多くの列 (特に 論理列) を要求するのは避けてください。 論理列には、異なるデータベース テーブルに格納されている値が含まれます。 AttributeMetadata.IsLogical プロパティ は、列が論理列であるかどうかを示します。 Dataverse には、他のデータベース テーブルからのデータを結合する必要があるため、多くの論理列を含むクエリは遅くなります。
フィルター条件の先頭にワイルド カードを使用しない
先頭にワイルド カードが付いた条件 (明示的に、または ends-with
のような演算子を使用して暗黙的に) を使用するクエリは、パフォーマンスが低下する可能性があります。 先頭にワイルド カードを使用したクエリで Dataverse はデータベース インデックスを利用できないため、SQL はテーブル全体をスキャンすることになります。 テーブル スキャンは、結果セットを制限する他の非先行ワイルドカード クエリがある場合でも発生する可能性があります。
次の例は、先頭にワイルド カードを使用する FetchXml 条件要素 です。
<condition attribute='accountnumber'
operator='like'
value='%234' />
クエリがタイムアウトし、このパターンが検出されると、Dataverse はこのパターンを使用しているクエリを識別するのに役立つ一意のエラーを返します。
名前:
LeadingWildcardCauseTimeout
コード:0x80048573
番号:-2147187341
メッセージ:The database operation timed out; this may be due to a leading wildcard value being used in a filter condition. Please consider removing filter conditions on leading wildcard values, as these filter conditions are expensive and may cause timeouts.
Dataverse は、稼働停止を回避するために、環境の正常性に対するリスクとして特定される、先頭にワイルドカードを含むクエリの 大幅な調整を行います。 調整が原因でクエリが失敗し、このパターンが検出されると、Dataverse は一意のエラーを返します。
名前:
DataEngineLeadingWildcardQueryThrottling
コード:0x80048644
番号:-2147187132
メッセージ:This query cannot be executed because it conflicts with Query Throttling; the query uses a leading wildcard value in a filter condition, which will cause the query to be throttled more aggressively.
先頭にワイルド カード クエリを使用している場合は、次のオプションをご検討ください。
- 代わりに Dataverse 検索 を使用する。
- 先頭のワイルド カードを必要性を避けるため、データ モデルを変更します。
その他のワイルドカード文字がある場合
文字列値の条件でワイルドカード文字を使用するで説明されているように、パーセント記号 ('%') 文字を超える他の文字はワイルド カードのように機能します。 次の 2 つのクエリ文字列の例は、先頭のワイルドカードのように動作します。
_234%
[^a]234%
Dataverse は、これらの他の先導ワイルドカード特殊文字で始まる検索文字列を含むクエリを大幅に制限します。
ハイフン文字
データベース照合順序の Unicode 並べ替え規則により、ハイフン ('-') で始まる一部の検索文字列は、先頭のワイルドカード検索のように機能します。 ハイフンで始まる検索文字列は、文字列内に '%' 文字が出現する前にワイルドカード以外の文字が検索文字列に含まれていない場合、データベース インデックスを利用できません。 たとえば、-%
と -%234
はデータベースのインデックスを効率的に利用できませんが、-234%
は利用できます。 Dataverse は、ハイフンで始まる非効率的な検索文字列を大幅に制限します。 ハイフンに関するデータベース照合のユニコードの並べ替え規則についてさらに詳しく知りたい場合は、 SQL Server の照合順序を参照してください。
フィルター条件で数式や計算列を使用しない
式と計算済みの列 の値は、取得時にリアルタイムで計算されます。 これらの列にフィルターを使用するクエリは、フィルターを適用できるように、返される可能性のある各レコードの値を Dataverse に計算させます。 クエリが遅くなるのは、Dataverse は SQL を使用してこれらのクエリのパフォーマンスを向上させることができないためです。
クエリがタイムアウトし、このパターンが検出されると、Dataverse はこのパターンを使用しているクエリを識別するのに役立つ一意のエラーを返します。
名前:
ComputedColumnCauseTimeout
コード:0x80048574
番号:-2147187340
メッセージ:The database operation timed out; this may be due to a computed column being used in a filter condition. Please consider removing filter conditions on computed columns, as these filter conditions are expensive and may cause timeouts.
Dataverse は、稼働停止を回避するために、環境の正常性に対するリスクとして特定されたクエリの 大幅な調整を行います。 調整が原因でクエリが失敗し、このパターンが検出されると、Dataverse は一意のエラーを返します。
名前:
DataEngineComputedColumnQueryThrottling
コード:0x80048744
番号:-2147186876
メッセージ:This query cannot be executed because it conflicts with Query Throttling; the query uses a computed column in a filter condition, which will cause the query to be throttled more aggressively.
選択列別の並べ替えを避ける
FetchXml または QueryExpression を使用する場合、選択肢列を使用してクエリ結果を並べ替えるときに、各選択肢オプションのローカライズされたラベルを使用して結果が並べ替えられます。 データベースに保存されている数値で並べ替えると、アプリケーションで良いエクスペリエンスが得られません。 選択列の順序付けには、ローカライズされたラベル値で行を結合して並べ替えるために、より多くのコンピューティング リソースが必要です。 この余分な作業により、クエリが遅くなります。 可能であれば、選択列の値で結果を並べ替えないようにしてください。
ヒント
OData は違います。 Dataverse Web API では、$orderby
ローカライズされたラベルではなく、選択肢列の整数値を使用して行を並べ替えます。
関連テーブル内の列別の順序付けを避ける
関連テーブルの列別に並べ替えると、複雑さが増すためクエリが遅くなります。
関連するテーブル別の並べ替えは、ここで説明するように必要な場合にのみ実行してください。
大規模なテキスト列での条件の使用を避ける
Dataverse には、大規模なテキスト文字列を格納できる 2 種類の列があります。
- StringAttributeMetadata は最大 4,000 文字まで保存できます。
- MemoAttributeMetadata は、より大きな数値を保存できます。
これら両方の列の制限は、MaxLength
プロパティを使用して指定されます。
850 文字未満に設定された MaxLength
を持つ文字列に対して条件を使用できます。
850 文字を超える MaxLength
を持つすべてのメモ列や文字列列は、大規模なテキスト列として Dataverse で定義されます。 大規模なテキスト列は、効果的にインデックスを作成するには大きすぎるため、フィルター条件に含めるとパフォーマンスが低下します。
このような種類の列のデータをクエリ処理するには、Dataverse 検索の方が適しています。
アンチパターンが原因で発生したクエリ タイムアウトの Dataverse エラー
クエリがタイムアウトし、このページで説明されているアンチパターンのいずれかを使用している場合、Dataverse はクエリが使用しているアンチパターンを特定する以下の一意のエラーを返します。
名前:
PerformanceValidationIssuesCauseTimeout
コード:0x80048575
番号:-2147187339
メッセージ:The database operation timed out; this may be due to the query performance issues identified in a query executed on this request. Please optimize the query by addressing the following identified performance issues: {0}. Please reference this document for guidance: https://go.microsoft.com/fwlink/?linkid=2300520
例外メッセージの {0}
部分には、クエリが使用しているアンチパターンが列挙されています。 クエリで使用されるアンチパターンが複数ある場合は、コンマで区切られます。 たとえば、クエリが大きなテキスト列でフィルター処理を行い、さらに多数の列を選択している場合、例外メッセージには PerformanceLargeColumnSearch,LargeAmountOfAttributes
という文字列が含まれます。 次の表に、アンチパターンと説明へのリンクを示します。
アンチパターン識別子 | 説明のリンク |
---|---|
PerformanceLeadingWildCard |
フィルター条件の先頭にワイルド カードを使用しない |
PerformanceLargeColumnSearch |
大規模なテキスト列での条件の使用を避ける |
OrderOnEnumAttribute |
選択列別の並べ替えを避ける |
OrderOnPropertiesFromJoinedTables |
関連テーブル内の列別の順序付けを避ける |
LargeAmountOfAttributes |
選択した列の数を最小限にする |
LargeAmountOfLogicalAttributes |
選択した論理列の数を最小限にする |
FilteringOnCalculatedColumns |
フィルター条件で数式や計算列を使用しない |
このページのガイダンスを使用してアンチパターンを理解し、これらのアンチパターンの使用を回避するようにクエリを変更します。
ヒント
クエリに PerformanceLeadingWildCard
または FilteringOnCalculatedColumns
のアンチパターンが含まれている場合、異なる Dataverse のエラーがスローされます。
PerformanceLeadingWildCard
のアンチパターンを使用するクエリは、このページに記載されている LeadingWildcardCauseTimeout
のエラーをスローします。また、FilteringOnCalculatedColumns
のアンチパターンを使用するクエリは、このページに記載されている ComputedColumnCauseTimeout
のエラーをスローします。
LeadingWildcardCauseTimeout
と ComputedColumnCauseTimeout
のエラーは PerformanceValidationIssuesCauseTimeout
のエラーより前に発生しており、LeadingWildcardCauseTimeout
と ComputedColumnCauseTimeout
は後方互換性を維持するために引き続きスローされます。
関連記事
クエリの調整
文字列値の条件でワイルドカード文字を使用する
FetchXML を使用してデータのクエリを実行する
QueryExpression を使用したデータのクエリ
OData を使用してデータのクエリを実行する