質問

複数の(ネストされた)サブQueriesを備えたやや複雑なクエリがあります。これは、アプリケーション開発者が利用できるようにしたいと考えています。クエリは汎用であり、データセットのコレクションにわたって計算された値でビューを生成します。開発者は、クエリが返すものからいくつかのレコードのみを必要とすると予想されます(つまり、一部のエンティティのIDまたは日付範囲の結果を制限します。そのような)。

これを実装する3つの方法がわかります。

  1. 開発者に各アプリケーションにクエリを埋め込み、独自のアプリケーションを追加します WHERE 必要に応じて条項。
  2. パラメーターとして受け入れるストアドプロシージャを作成して、開発者が必要とするすべての条件として(引数のために必要なものを予測できると言うことができます)、手順は複雑なクエリを実行してフィルタリングします渡されたパラメーターによると。
  3. いくつかのサブビューを使用してビューとしてクエリを実装します(MySQLがビューでサブQuerieを許可しないため)、開発者にこれをテーブルとして使用して使用させます WHERE 各アプリケーションを使用するには、必要なフィルターを適用します。現在、私は3つの追加のサブビューを見ています。これは主にいくつかのサブQuerieが複数回使用され、サブビューとしてそれらを行うと重複を防ぐためです。

パフォーマンスが賢くなるのは何ですか? (すべての場合にすべてのインデックス作成が同等であると仮定すると)最悪のシナリオを使用できます。

コードメンテナンスの条件で何が良くなると思いますか?

役に立ちましたか?

解決

私は「良い」を定義する質問が好きです - あなたはパフォーマンスと保守性について具体的に尋ねました。これにより、答えはそのトレードオフについて話すことができます。

パフォーマンスの観点からは、予想されるシナリオ内にクエリとデータが適合している限り、3つのオプションに違いがあるとは思わない。私は100倍のデータでテストし、潜在的に「ここで」句を拡大して何が起こるかを確認しますが、インデックス構造などは、貯蔵されたProcから同じSQLを実行するかどうかよりもパフォーマンスに影響を与える可能性が高くなります。表示、またはクライアントアプリケーションから。

その質問に答える最良の方法は、それをテストすることです。もちろん、一般的な「私はx、y、zを期待する」という答えを無効にする可能性のある多くの具体的な詳細があります。パフォーマンスが重大な懸念事項である場合は、データベース充填ツール(Redgate Make On、過去にdbmonsterを使用しました)を使用し、3つのオプションすべてを試してみてください。

ビューのメンテナンスポイントから、私はオプション4を提供します。これは、私の見解では、はるかに最適です。

オプション4:データへのアクセスをカプセル化するデータアクセスライブラリを構築します。ライブラリにメソッドとパラメーターを公開して、レコードの選択を改善します。仕様パターン(http://en.wikipedia.org/wiki/specification_pattern)の使用を検討してください。ライブラリ内で最適なクエリを使用し、実装の詳細を開発者に悩ませないでください。

それがうまくいかない場合 - 不均一なアプリケーションコード、単純な要件のためにあまりにも多くの変更 - 次のようにオプションを評価します。

  1. 埋め込みSQL:このSQLが再利用される回数に応じて、これは大丈夫かもしれません。 SQLを実行するコードの部分が1つしかない場合、それは論理的にデータアクセスライブラリに似ています。ただし、同じスニペットが多くの場所で再利用される必要がある場合、それはバグの可能性のあるソースです - SQLの小さな変更をいくつかの場所で繰り返す必要があります。

  2. ストアドプロシージャ:私は通常、メンテナンスの理由でストアドプロシージャを嫌います - それらは過負荷によって脆くなる傾向があり、手続き的な考え方を作成します。たとえば、このSQL計算を別のストアドプロシージャで使用するための他の要件がある場合、非常に迅速に、保存されたProcsが互いに呼び出す手続き上のプログラミングモデルになります。

  3. ビュー:これはおそらく最良の選択です。特定のデータロジックを単一の場所に配置しますが、アクセスルートは手続き的なステートメントを実行するのではなく、選択されたステートメントを使用するため、セットベースのロジックの使用を促進します。ビューは、他のクエリに簡単に組み込むことができます。

他のヒント

適切に実装されていれば、3つのソリューションのいずれかがマンテイナンスに適していますが、移行プロセス(コードまたはデータベースの移行)でそれぞれをどのように扱うかを覚えておいてください。

クエリが大きい場合、ストアドプロシージャはあなたに少し余分に与えます パフォーマンス より小さなサイズのクエリを送信しているため、頭上の帯域が少ないためです。また、このソリューションで少し余分なセキュリティを得ることができます。

のために マンテイナンス 解決策、私はデータベースの変更を行わずにクエリに変更を加えることができます。最初のソリューションを選択した場合、機能内でクエリコールをラップして、変更を加える場所が1つしかありません。

から 開発者の視点, 、私はビューソリューションビーチューズが最も透明なものであることを選択します。つまり、通常のテーブルのみをクエリするようなものであるか、説明コマンドでテーブル構造を確認するか、クエリする必要があるフィールドと条件を選択するか、別のフィールドと結合することができます。テーブルなど...

関して 条項の柔軟性, 、提案されたソリューションのいずれかでそれを達成することができます。ラッピング関数(1)にパラメーターを追加するには、Whereパラメーターをストアドプロシージャに追加できますが、注入(2)に注意することができます。

MySQLのビューは一時的なテーブルではないことを念頭に置いて、 クエリが非常に複雑な場合 このソリューションは、クエリが多くの方法でさまざまな方法で使用されている場合(キャッシュパフォーマンスの向上を無効にする)、最善ではありません。 一時的なテーブルを検討します プログラムされたタスク /クロン(たとえば、必要なときに1日、1週間)で各期間を更新するソリューション(カウンターテーブル)またはプロッパートリガーを設定して更新されます。このソリューションは、パフォーマンスを大幅に向上させる可能性があります。

これが役立つことを願っています、私はビューソリューションが最も好きですが、データベースの観点から発展する方が複雑かもしれません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top