3

ログ検索速度とディスクサイズに問題があります。これは非常に大きく、約 2 億 2000 万の行と 25 ギガバイトのディスク サイズがあり、一部の選択をフェッチするのに数分かかります。

それはどのように機能しますか?ログは Sql Anywhere を使用してデータベースに保存されます。現在はバージョン 9 であり、まもなく 11 に移行されます (12 にしようとしましたが、いくつかのドライバーといくつかの問題のために 11 に戻りました)。

ログは 2 つのテーブルで構成されています(ここにいる人々が理解できるように、名前は英語に変更されています)。

ログテーブル

Id、DateTime、User、Url、Action、および TableName。 Action は使用されたものです: insert/delete/update TableName は、データベース内のどのテーブルが影響を受けたかです。

LogTableFields

Id、LogTable_Id、FieldName、NewValue、OldValue。 LogTable_Id は LogTable からの外部キーです。FieldName は、DB からのテーブルのフィールドです。

NewValue と OldValue は varchar 型であることに注意してください。他のテーブルのあらゆる種類のフィールド (datetime、int など) が記録されているためです。

なぜこのように作られたのですか? 重要なことはすべて記録しなければならないからです。このシステムは機関の交通局向けに作成されており(適切な英語でこのように綴られているかどうかはわかりませんが、これが何であるかはわかります)、ある種のランダムレポートを要求することがあります.

これまでは、SQL の選択を行うだけでレポートを作成してきました。ただし、datetime がフィルター処理されたとしても、完了するまでに数分かかります。頻繁にリクエストされていないときに文句を言うのではありません。

しかし、彼らは、素敵で美しいレポートを備えた機能をソフトウェアに作成する必要があるというレポートをますます要求しています. 彼らのニーズがわからないので、ログに戻ってデータをアンベリーする必要があります。

要求された一部の情報は、ログにのみ含まれています。(例: どのユーザーが誰かに車両への不適切なアクセスを許可したか)

これまでに提案されたいくつかのアイデア:

アイデア 1:いくつかの調査を行ったところ、 CouchDB を使用して NoSql を操作するように言われました。しかし、私が読んだ少しのことでは、NoSql は私の問題の解決策ではないと感じています。経験がないのに理由を議論することはできません。

アイデア 2: ログ テーブルをデータベースまたはマシンから物理的に分離します。

アイデア 3: バージョン フィールドを持つすべてのテーブルからミラーを作成し、履歴を保持します。

必要に応じて、マクロの最適化またはアーキテクチャの変更をお願いします。

4

2 に答える 2

1

適切なインデックスを追加することが、最大の改善になります。あなたはインデックスを持つことについて言及していないので、何も持っていないと思います。それはそれを非常に遅くするでしょう。

たとえば、クエリを DateTime の特定の範囲に制限しても、DateTime にインデックスがない限り、まったく役に立ちません。インデックスがない場合でも、データベースは 25 GB のほぼすべてのデータにアクセスして、適切な時間範囲にある少数の行を見つける必要があります。しかし、インデックスを使用すると、関心のある時間範囲内にある少数の行をすばやく特定できます。

一般に、時間がかかりすぎるクエリを実行するためにデータベースがどのプランを使用しているかを常に確認する必要があります。私は Sql Anywhere に特に精通していませんが、これを実行できる Plan Viewer があることは知っています。大規模なシーケンシャル スキャンを識別し、代わりにそれらのフィールドにインデックスを配置する必要があります。

テーブルを分割し、整数の外部キーを使用することで、測定可能な改善が得られるとは思えません。クエリが多くの列に触れる範囲で、いずれにせよそれらすべてのテーブルを再び結合することになります。

于 2012-01-18T06:23:40.993 に答える
1

これはかなり標準的な監査テーブルのようです。このためにNoSQLソリューションに行く必要があるかどうかはわかりません。2 億 2000 万行は、ほとんどの RDBM で快適に処理されます。

最大の問題はテーブル構造にあるようです。通常、テーブルを平坦化してロギング速度を向上させ、正規化してレポート速度を向上させます。ご覧のとおり、これらは矛盾しています。

MS SQL などを使用している場合は、パフォーマンスのログ記録用に 1 つのフラット テーブルを構築し、その上に単純な Analysis Services キューブを構築できます。

もう 1 つのオプションは、十分なログ スループットを維持できると仮定して、レポート用に最適化することです。そのためには、次のような構造を作成する必要があります。

テーブル LogTable を作成します (
  LogTableID int ID(1,1),
  テーブル名 varchar(100),
  URL varchar(200)
)

テーブル LogUser を作成します (
  LogUserID int indentity(1,1),
  ユーザー名 varchar(100)
)

テーブル LogField を作成します (
  LogFieldID int ID(1,1),
  フィールド名 varchar(100),
)

テーブル LogData を作成します (
  LogDataID bigint ID(1,1),
  LogDate日時、
  LogTableID int は LogTable(LogTableID) を参照し、
  LogFieldID int は LogField(LogFieldID) を参照し、
  LogUserID int は LogUserID(LogUserID) を参照し、
  アクション char(1), -- U = 更新、I = 挿入、D = 削除
  OldValue varchar(100),
  NewValue varchar(100)
)

これは、データをすばやくログに記録するのに十分な速さである必要がありますが、レポート作成には十分なパフォーマンスを提供します。インデックスの設計も重要で、通常はカーディナリティの高い順に行われます。たとえば、LogData(LogTableID, LingFieldID, LogDate) のようになります。並列化されたクエリを可能にするために、パーティショニングに夢中になることもできます。

于 2012-01-14T08:45:33.743 に答える