0

次のテーブルがあるとします

CREATE TABLE `entities` (
   `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
   `timestamp` TIMESTAMP NOT NULL
      DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   `data` VARCHAR(255),
   PRIMARY KEY (`id`,`timestamp`)
);

各エンティティは通常、 によってのみ参照されますid。ただし、エンティティごとに複数のリビジョンがあり、 によって明確にされていtimestampます。私のクエリの大部分は最新のリビジョンを選択するもので、新しいリビジョンを挿入するのはほんの一握りで、過去のリビジョンをすべて選択するのはさらに少数です。私は、平均して 1 ダース程度の改訂しか期待していませんid

最新のリビジョンを選択する最も効率的な (パフォーマンスとストレージ容量の点で) 方法は何ですか? この問題に対して受け入れられている慣行はありますか?

私が見ているように、2 つの方法があります。GROUP BY

CREATE VIEW groupedEntities AS
   SELECT id, max(timestamp) AS maxt FROM entities GROUP BY id;
CREATE VIEW currentEntities AS
   SELECT a.id, data, timestamp FROM groupedEntities AS a
      INNER JOIN entities AS b ON b.id=a.id AND b.timestamp=a.maxt
      WHERE timestamp <= CURRENT_TIMESTAMP;
SELECT * FROM currentEntities WHERE id=?;

<=CURRENT_TIMESTAMPタイムスタンプを遠い未来に設定することにより、エンティティを「削除」できることに注意してください。(2) 現在のリビジョンを保存する別のテーブルを作成する

CREATE TABLE currentEntities (
   `id` INT(10) UNSIGNED PRIMARY KEY,
   `timestamp` TIMESTAMP,
   CONSTRAINT FOREIGN KEY (`id`, `timestamp`)
      REFERENCES `entities` (`id`,`timestamp`)
);
SELECT * FROM currentEntites INNER JOIN groupedEntities WHERE id=?;

または他のオプション(3)?

4

1 に答える 1

0

MySQL がビューを処理する方法のため、ビューはパフォーマンスの面で昼食を食べます。具体的には、MySQL はビューの中間 MyISAM テーブルを実体化し、述語を外部クエリからビュー (格納またはインライン) に「プッシュ」しません。

頻繁に使用される「現在の」リビジョンを保持する別のテーブルを持つオプションは、提示する2つのオプションよりも優れています。これにより、複雑さが増し、すべてが同期され、現在と履歴を取得するための異なるクエリが発生し、追加の挿入のオーバーヘッドが発生します。

元のテーブルだけを指定すると (すべての履歴リビジョンを現在のリビジョンと同じテーブルに保存します (最新のリビジョンだけの別のテーブルはありません)...

ビュー定義の内側に述語を含むインライン ビューを使用したクエリは、最高のパフォーマンスを発揮します。

SELECT e.id
     , e.timestamp
     , e.data
  FROM `entities` e
  JOIN ( SELECT m.id 
              , MAX(m.timestamp) AS `timestamp`
           FROM `entities` m
          WHERE m.id = ?
          GROUP BY m.id
       ) c
     ON c.id = e.id 
    AND c.timestamp = e.timestamp

EXPLAIN 出力ではUsing where; Using index、インライン ビュー (派生テーブル) を具体化するステップで " " が表示されます。data外部クエリの結合述語は、列の検索に最適な主キーによるものです。

于 2013-11-15T01:05:12.663 に答える