3

次のフィールドを持つ「team_sector」テーブルがあります: Id、team_id、sect_id、サイズ、レベル

「チーム」エンティティごとにいくつかのレコードが含まれています (「team_id」フィールドで参照されます)。各レコードは、チームのスタジアムのセクター (合計 8​​ セクター) を表します。

ここで、いくつかの検索を実装する必要があります。

  • スタジアム全体のサイズ (SUM(size));
  • 最高品質 (SUM(レベル)/COUNT(*))。

次のようなクエリを作成できます。

SELECT TS.team_id, SUM(TS.size) as OverallSize, SUM(TS.Level)/COUNT(TS.Id) AS QualityLevel
FROM team_sector
GROUP BY team_id
ORDER BY OverallSize DESC / ORDER BY QualityLevel DESC

しかし、ここでの私の懸念は、クエリが実行されるたびに各チームの計算が行われることです。オーバーヘッドはそれほど大きくありませんが (少なくとも現在は)、後でパフォーマンスの問題を回避したいと考えています。

ここに 2 つのオプションがあります。

1 つ目は、「チーム」テーブルに 2 つの追加フィールドを作成し (たとえば)、OverallSize フィールドと QualityLevel フィールドをそこに格納することです。「セクター」テーブルが変更された場合の情報 - それらのテーブルも更新します (セクター テーブルはあまり頻繁に変更されないため、おそらくトリガーを使用して更新することをお勧めします)。

2 番目のオプションは、必要なデータを提供するビューを作成することです。

2 番目のオプションは、私にとってははるかに簡単に思えますが、ビューを操作する経験や知識があまりありません。

Q1:ここであなたの観点から最良の選択肢は何ですか? またその理由は何ですか? おそらく、他のオプションを提案できますか?

Q2:まれに (少なくとも 1 日に 1 回) 計算を行うようにビューを作成できますか? はいの場合 - どのように?

Q3:そのような目的でトリガーを使用することは合理的ですか (第 1 のオプション)。

PS MySql 5.1 が使用され、チームの総数は約 1 ~ 2,000、セクター テーブル内のレコードの総数は、全体で 6 ~ 8,000 です。これらの数はかなり少ないことは理解していますが、ここでベスト プラクティスを実装したいと思います。

4

2 に答える 2

2

ソーステーブルに計算フィールドを追加しません。代わりに一時テーブルを使用して、ソースデータを計算データから分離してください。共有PKによって識別される1対1のマッピングを使用して、インデックスなどを減らすことでパフォーマンスを向上させることができます(したがって、ソース行のPKは計算されたテーブルの行のPKと等しくなります)。

利点は、DBを再構築するときに、テーブルがないために計算されたデータが古くなっていることは明らかです。また、cronジョブなどによって一時テーブルを削除するだけで、計算されたすべてのデータをクリアするなどのショートカットも可能です。このようにして、計算されたデータ行は、データが計算されたときのタイムスタンプも保持する場合があります。このようにして、最大キャッシュ期間が満了した場合、計算されたデータは、ロード時にオンザフライで再計算されるか、サーバーが静かな夜間にバッチとして再計算されます。

于 2011-01-02T19:37:14.183 に答える
1

数万のレコードは、心配する必要はありません。

ベストプラクティスは

  • 正規化された方法でデータを保存し、データベースエンジンに計算を処理させます
  • データに適切なインデックスを付け、インデックスのメンテナンスを時々行います
  • 集計値を「親」レコードと一緒に保存することは避けてください
  • 必要以上に頻繁にDBサーバーにアクセスしないように、アプリケーション層で結果のキャッシュを実行します
  • パフォーマンスの問題を取得したら対処する

はい、データベースはSUM()ビュー/クエリが実行されるたびに計算しますが、説明したシナリオでは結果がすぐに得られると思います。

計算に時間がかかり、テーブルをさらに最適化する方法が見つからない非常に複雑なビューに遭遇した場合は、ビューの結果が定期的に(またはトリガーを介して)入力されるヘルパーテーブルを導入してクエリを実行できます。スロービューの代わりにそのテーブル。

IMHOは、パフォーマンスのボトルネックの可能性を予測し、実際に現れる前にそれらを「閉じる」ことで時間を無駄にしています。

于 2011-01-02T19:50:21.953 に答える