13

私は Web プロジェクト (asp.net) で約 6 か月間働いています。最終製品がまもなく公開されます。プロジェクトでは、SQL Server をデータベースとして使用します。大量のデータを使用してパフォーマンス テストを行った結果、データが大きくなりすぎると、たとえば 200 万行になるとパフォーマンスが低下することが示されました (タイムアウトの問題、応答の遅延など)。最初は完全に正規化されたデータベースを使用していましたが、現在はパフォーマンスの問題により部分的に正規化されています (結合を減らすため)。まず、その判断は正しいですか?さらに、データサイズが非常に大きくなった場合に可能な解決策は何ですか? のクライアントは今後増加しますか?

さらに追加したいと思います:

  • 200 万行はエンティティ テーブルであり、関係を解決するテーブルにはさらに大きな行があります。
  • データ + no の場合、パフォーマンスが低下します。利用者が増える。
  • 頻繁に使用されるクエリを特定した後、非正規化が行われました。
  • また、大量の xml 列と xquery も使用しています。これが原因でしょうか?
  • トピックから少し外れましたが、私のプロジェクトの一部の人々は、動的 SQL クエリはストアド プロシージャ アプローチよりも高速であると言っています。彼らは、その主張を証明するために何らかのパフォーマンス テストを行いました。私はその逆だと思います。頻繁に使用されるクエリの一部は動的に作成されますが、他のほとんどのクエリはストアド プロシージャにカプセル化されています。
4

14 に答える 14

30

物事のスキームでは、数百万行は特に大きなデータベースではありません。

OLTPデータベースについて話していると仮定すると、ボトルネックの根本原因を最初に特定せずに非正規化することは、非常に悪い考えです。

最初に行う必要があるのは、代表的な期間にわたってクエリワークロードをプロファイリングして、ほとんどの作業が行われている場所を特定することです(たとえば、SQLServerを使用している場合はSQLProfilerを使用します)。クエリが実行する論理読み取りの数に実行された回数を掛けたものを見てください。パフォーマンスが最も低い上位10個のクエリを特定したら、クエリ実行プランを詳細に調べる必要があります。

私はここで手足に出かけるつもりです(それは通常そうなので)、しかしあなたの問題がどちらでもないなら私は驚かれることでしょう

  1. コストのかかるクエリのインデックスをカバーする「正しい」ものがない
  2. 構成が不十分であるか、指定されたディスクサブシステムの下にある

このSOの回答は、ワークロードで最もパフォーマンスの低いクエリを見つけるためにプロファイリングする方法を説明しています。

于 2008-10-03T09:25:49.850 に答える
13

古いことわざにあるように、「痛くなるまで正常化し、機能するまで非正規化する」。

私はこれが大好きです!これは通常、もはや受け入れてはならない種類のものです。一度にDBASEIII4 つ以上のテーブルを開くことができなかった時代 (AUTOEXEC.BAT パラメーターの一部を変更してコンピューターを再起動しない限り、ああ! ...) では、非正規化に関心があったことが想像できます。

しかし最近では、庭師が津波を待って芝生に水をやるのと同じような解決策を見ています。利用可能な水まき缶 (SQL プロファイラー) を使用してください。

また、データベースの一部を非正規化するたびに、それをさらに適応させる能力が低下し、コードのバグのリスクが高まり、システム全体の持続可能性が低下することを忘れないでください。

于 2008-10-03T11:08:27.177 に答える
8

保存する情報の種類にもよりますが、通常、200 万行は超大規模データベースではありません。通常、パフォーマンスが低下した場合は、インデックス作成戦略を確認する必要があります。SQL Server データベース エンジン チューニング アドバイザーが役立つ場合があります。

于 2008-10-03T09:07:07.280 に答える
3

その理由は無数にあります。SQL プロファイラーとクエリ アナライザーを使用して、"スキーマ変更" の道をたどる前に、クエリが遅くなる理由を特定します。いくつかのインデックスを作成し、「統計の更新」をスケジュールするだけでよいということはまずありません... ...しかし、前述したように、Profiler と Query Analyzer は、何が起こっているのかを調べるための最良のツールです.. .

于 2008-10-03T09:11:23.387 に答える
1
  • まず、データベースが適度に正常であることを確認し、可能であればデータベースでDBCC DBREINDEXを実行し、パフォーマンスに影響を与える余裕がない場合はDBCCINDEXDEFRAGを実行して統計を更新します。

  • プロファイラーを妥当なサンプル時間で実行します。これは、一般的な関数のほとんどをキャプチャするのに十分ですが、10秒などの長さでフィルター処理します。数ミリ秒しかかからないことは気にせず、それらを見ることさえしません。 。

  • 実行時間の長いクエリができたので、それらからsnotを調整します。最も表示されるものを取得し、クエリアナライザで実行プランを確認し、時間をかけて理解し、必要に応じてインデックスを追加して、取得を高速化します。

  • カバーされたインデックスの作成を見てください。SELECT * FROM ...を実行している場合は、必要に応じてアプリを変更します。SELECTLASTNAME、FIRSTNAME...のみが必要な場合。

  • パフォーマンスが期待どおりになるまで、5秒、3秒などの期間でプロファイラーサンプリングを繰り返します。

于 2008-10-04T00:32:56.623 に答える
1

最初は完全に正規化されたデータベースを使用していましたが、現在はパフォーマンスの問題により (結合を減らすために) 部分的に正規化されています。

古いことわざにあるように、「痛くなるまで正常化し、機能するまで非正規化する」。

大規模で頻繁に使用されるデータベースでは、パフォーマンスを向上させるためにある程度の非正規化が見られることはかなり一般的であるため、パフォーマンスが希望どおりであり、コードを管理する必要がある限り、今はあまり心配しません。 「非正規化された」フィールドはそれほど面倒になりません。

データサイズが非常に大きくなった場合に可能な解決策は何ですか? のクライアントは今後増加しますか?

アプリケーションのドメインについてあまり詳しくないため、それを将来的に保証する方法を言うのは困難ですが、最近使用したデータと古いデータを分割してテーブルを分離することは、トラフィックの多いデータベースではかなり一般的なアプローチです。ユーザーの 95% が過去 30/45 日間のデータをクエリし、たとえば過去 60 日間のデータを含む「live_data」テーブルと古いデータ用の「old_data」を用意すると、パフォーマンスが向上します。

データと負荷が増加するにつれてデータベースのパフォーマンスを測定できるように、広範なパフォーマンス監視が設定されていることを確認することをお勧めします。パフォーマンスが著しく低下した場合は、インデックスを再検討する時期かもしれません。

于 2008-10-03T09:07:45.453 に答える
1

それは正しい決断ではないかもしれません。すべての DB インタラクションを特定し、それらを個別にプロファイリングしてから、問題のあるものを見つけて、そこでのパフォーマンスを最大化するための戦略を立てます。また、DB の監査ログを有効にしてそれらをマイニングすると、最適化ポイントが向上する可能性があります。

于 2008-10-03T09:07:52.273 に答える
1

OLTP タイプのデータを非正規化して、コア データが「汚染」されるのを防ぐのが最善だと思います。それは途中であなたを噛むでしょう。

ボトルネックがレポートまたは読み取り専用のニーズによるものである場合、個人的には、正規化された「本番」テーブルに加えて非正規化されたレポート テーブルを使用しても問題はないと思います。クエリを迅速に行うために必要なレベルにロールアップするプロセスを作成します。読み取り専用の方法でのみ使用されるテーブルを定期的にロールアップして非正規化する単純な SP または夜間のプロセスは、多くの場合、ユーザー エクスペリエンスに大きな違いをもたらします。

結局のところ、システムが遅いという理由で誰もシステムを使用したくないのであれば、理論的にクリーンで完全に正規化された一連のデータを持っていても何のメリットがあるでしょうか?

于 2009-04-26T14:34:37.383 に答える
0

あなたはどんな仕事でもする権利があります。
...後で支払う代償があるかもしれないことに気付いている限り。とにかくこれについて考えているようですね。

チェックすること:

デッドロック

  • すべてのプロセスが同じ順序でテーブルにアクセスしていますか?

遅さ

  • テーブルスキャンを実行しているクエリはありますか?
    • 大きな結合(4つ以上のテーブル)を確認します
    • あなたのindecesをチェックしてください

一般的なパフォーマンスのヒントに関する他の投稿を参照してください。

于 2008-10-03T13:50:57.167 に答える
0

興味深い...ここにたくさんの答えがあります。

rdbms / osバージョンは64ビットですか?

パフォーマンスの低下は数倍であるように見えます。その理由の一部は確かに索引付けによるものです。データの保存方法と一致する方法でいくつかのテーブルをパーティション化することを検討しましたか?つまり、データの入力方法に基づいて(順序に基づいて)パーティションを作成します。これにより、インデックスの大部分が静的であるため、パフォーマンスが大幅に向上します。

もう1つの問題はxmlデータです。xmlインデックスを利用していますか?オンラインブック(2008)から「プライマリXMLインデックスを使用して、次のタイプのセカンダリインデックスがサポートされています:PATH、VALUE、およびPROPERTY」。

最後に、システムは現在、多くの動的SQLを実行/実行するように設計されていますか?その場合、計画を生成し、再生成し、ほとんど再実行する必要がないため、メモリパースペクティブからの分離が発生します。私はこれをメモリチャーンまたはメモリスラッシングと呼んでいます。

HTH

于 2009-05-08T17:44:39.317 に答える
0

数百万のレコードは、SQLServerにとって小さなデータベースです。大量の結合があり、汗をかくことなく、テラバイトのデータを処理できます。設計上の問題があるか、クエリの記述が非常に不十分である可能性があります。

ライブに移行する前のパフォーマンステストに対する称賛。何ヶ月または何年も本番環境に移行した後は、この問題を修正するのは非常に困難です。

あなたがしたことはおそらく悪い選択です。非正規化する場合は、データの同期を維持するためにトリガーを設定する必要があります。あなたはそれをやりました?挿入と更新の時間がどのくらい長くなりましたか?

私の最初の推測は、外部キーにインデックスを付けなかったということです。

何が間違っている可能性があるかに関する他の推測には、次のようなものの乱用が含まれます。相関サブクエリスカラー関数ビュー呼び出しビューカーソルEAVテーブルsargabilityの欠如select *

テーブルのデザインが悪いと、パフォーマンスが低下する可能性もあります。たとえば、テーブルの幅が広すぎると、テーブルへのアクセスが遅くなります。データを使用するためにデータを別のデータ型に変換することが多い場合は、データが正しく保存されていないため、これは常にシステムの抵抗になります。

動的SQ1は、ストアドプロシージャよりも高速である場合がありますが、そうでない場合もあります。ここでパフォーマンスについて正しい答えはありません。内部セキュリティ(テーブルレベルで権限を設定する必要はありません)とデータベースへの変更の容易さのために、ストアドプロシージャの方が優れています。

プロファイラーを実行して、最も遅いクエリが何であるかを判断する必要があります。また、非常に頻繁に実行されるすべてのクエリを確認してください。クエリが1日に何千回も実行されると、小さな変更で大きな成果が得られます。

また、パフォーマンスチューニングに関する本を入手する必要があります。パフォーマンスの問題は多くの原因で発生する可能性があるため、これらはプロセス全体を支援します。データベース設計クエリ設計ハードウェアインデックス作成など。

迅速な解決策はありません。ランダムに非正規化すると、データの整合性を維持しない場合よりも問題が発生する可能性があります。

于 2010-04-22T13:48:23.587 に答える
0

インデックスとクエリを分析した後、ハードウェアを追加したい場合があります。あと数ギグのRAMがうまくいくかもしれません。

于 2008-10-04T19:28:58.937 に答える
0

まず、他の多くの人が数百万行は大きくないと言っています。私が取り組んでいる現在のアプリケーションには、すべて正規化された 1 億行以上のテーブルがいくつかあります。

パフォーマンスの低下に悩まされましたが、これはデフォルトのテーブル統計設定を使用したことが原因でした. テーブルの合計サイズに対して少数のレコードを挿入する、つまり、1 億件以上のレコードを含むテーブルに 100 万件のレコードを挿入しても、テーブルの統計情報が自動的に更新されないため、質の悪いクエリ プランが明らかになりました。並列ではなく逐次クエリが生成されます。

非正規化するのが正しい決定であるかどうかについては、スキーマによって異なります。深いクエリを定期的に実行する必要がありますか。つまり、定期的にアクセスする必要があるデータを取得するために大量の結合を実行する必要がありますか?

ただし、インデックス作成とテーブル統計の戦略を確認する前ではありません。
賢明で適切に構造化されたクエリを使用していること、および結合が適切に形成されていることを確認してください。クエリが実際に期待どおりに解析されていることをクエリ プランで確認してください。

他の人が言っているように、SQL Profiler/Database Engine Tuning Advisor は実際にうまく機能します。

私にとって、非正規化は通常、やることリストの一番下に位置しています。

それでも問題が解決しない場合は、サーバー ソフトウェアとハ​​ードウェアのセットアップを確認してください。

  • データベースとログ ファイルは、別々のコントローラを使用して別々の物理ディスク上にありますか?
  • 十分なメモリがありますか?
  • ログ ファイルは自動拡張に設定されていますか? そうであれば、autogrow の制限は低くなります。つまり、頻繁に増加します。
于 2008-10-03T12:23:59.760 に答える
0

私たちは常に、できるだけ「実世界」に近いデータベースを使用して開発を試みてきました。そうすれば、デバッグ中に接続がタイムアウトし続けると、昔の開発者は頭がおかしくなるので、このような多くの問題を回避できます。Sql パフォーマンスの問題をデバッグする最良の方法は、IMO が Mitch Wheat の提案です。profile を使用して問題のあるスクリプトを見つけ、それらから始めます。スクリプトを最適化すると、かなりの時間がかかる可能性があるため、インデックスを確認する必要があります。また、Sql Server に十分な処理能力があることを確認してください。特に IO (ディスク) が重要です。忘れないでください。キャッシュは王様です。メモリは安価です。もっと買う。:)

于 2008-10-03T11:37:08.227 に答える