1

データベース内のビッグデータの処理で次の問題が発生しています。

基本的に、デジタルセンサーからのすべての計測は、毎秒データベースに保存されます。すべてのデータからレポートに表示されるのは、発生した変更のみです。たとえば、時間Xで、レジスタ#1の値が0から1に変更されました。

必要なデータ(変更)のみを返すことができるプロシージャを作成しました。これにより、phpでの処理が大幅に節約されますが、大きな問題は、現在のデータが4日間の場合、クエリに6*Nかかることです。完了するまでの秒数。ここで、Nは選択されたレジスタの数です。

今、私はこの問題を克服するための最良の解決策は何であるか疑問に思いました。

別の考えは、データメータリングの新しい挿入ごとにトリガーを作成することですが、問題は、別のときに送信された以前のメータリングを調べる必要があるため、これがより複雑になることです。

そこで、何らかの形で新しいデータが到着したときに自動的に更新されるビューを作成することを考えました。つまり、レポートに対してリクエストが行われると、データの準備が整い、ビューからフェッチされます。

これは良い解決策になりますか?

4

2 に答える 2

0

テーブルは適切にインデックス付けされており、クエリはそれらのインデックスを適切に使用していると思いますか?

この場合、日付と登録の両方に1つずつ、複合インデックスから最も恩恵を受ける可能性があります。それぞれのインデックスが役立ちますが、両方の複合インデックスがはるかに役立ちます。

複合インデックスを追加するための構文は次のとおりです。

alter table yourTableName add index yourIndexName(col1, col2);

mysql> select * from table1;

+---------+------+------+-------------+
| autonum | ID   | name | metavalue   |
+---------+------+------+-------------+
|       1 |    1 | Rose | Drinker     |
|       2 |    1 | Rose | Nice Person |
|       3 |    1 | Rose | Runner      |
|       4 |    2 | Gary | Player      |
|       5 |    2 | Gary | Funny       |
|       6 |    2 | Gary | NULL        |
|       7 |    2 | Gary | Smelly      |
+---------+------+------+-------------+
7 rows in set (0.01 sec)

mysql> alter table table1 add index autoNumID(autonum, ID);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

もう1つ調べることができるのは、1つ(1時間ごとまたは1日ごとなど)更新される要約テーブルを作成することです。CRONなどを使用してクエリを実行すると、データの要約がはるかに小さなテーブルに作成され、レポートが機能します。

于 2012-09-14T10:10:45.383 に答える
0

既存のデータからステータスの変化を特定することは、単一のクエリで可能ですが、(あなたが発見したように)非常に費用がかかります。各ステータス変更をキャッシュに保存することをお勧めします。

@Fluffehが説明したように、適切なインデックスを使用すれば、既存のテーブルから最新のステータスを検索するのにそれほど費用はかかりません。したがって、トリガーアプローチは非常に合理的である必要があります。

したがって:

  1. 適切なインデックスを定義します(まだ存在しない場合)。

    ALTER TABLE existing_table ADD INDEX (register_id, timestamp);
    
  2. キャッシュ用のテーブルを作成します(オプションで、アプリケーションが直接変更できないようにユーザー権限を設定します)。

    CREATE TABLE status_changes VALUES (
      register_id ...,
      timestamp   TIMESTAMP,
      old_status  ...,
      new_status  ...,
    
      PRIMARY KEY                (register_id, timestamp),
    
      FOREIGN KEY                (register_id, timestamp, old_status)
       REFERENCES existing_table (register_id, timestamp, status),
    
      FOREIGN KEY                (register_id, timestamp, new_status)
       REFERENCES existing_table (register_id, timestamp, status)
    );
    
  3. 新しいテーブルを変更する権限を持つユーザーからのトリガーを定義します。

    DELIMITER ;;
    
    CREATE TRIGGER record_change AFTER INSERT ON existing_table FOR EACH ROW
    BEGIN
      DECLARE  _last_status ... ;
    
      SELECT   last.status
      INTO     _last_status
      FROM     existing_table AS last
      WHERE    last.register_id <=> NEW.register_id
           AND last.timestamp    <  NEW.timestamp
      ORDER BY last.timestamp DESC
      LIMIT    1;
    
      IF NOT NEW.status <=> _last_status THEN
        INSERT INTO status_changes (
          register_id,
          timestamp,
          old_status,
          new_status
        ) VALUES (
          NEW.register_id,
          NEW.timestamp,
          _last_status,
          NEW.status
        );
      END IF;
    END;;
    
    DELIMITER ;
    
  4. 履歴データから新しいテーブルにデータを入力します。

    INSERT IGNORE INTO status_changes (
      register_id,
      timestamp,
      old_status,
      new_status
    )
    SELECT NEW.register_id,
           NEW.timestamp,
           (
             SELECT   last.status
             FROM     existing_table AS last
             WHERE    last.register_id <=> NEW.register_id
                  AND last.timestamp    <  NEW.timestamp
             ORDER BY last.timestamp DESC
             LIMIT    1
           ) AS _last_status,
           NEW.status
    FROM   existing_table AS NEW
    WHERE  NOT NEW.status <=> (
             SELECT   last.status
             FROM     existing_table AS last
             WHERE    last.register_id <=> NEW.register_id
                  AND last.timestamp    <  NEW.timestamp
             ORDER BY last.timestamp DESC
             LIMIT    1
           )
    ;
    
于 2012-09-14T11:06:44.790 に答える