2013-06-07 12 views
5

今日の日付の30日前までにデータを必要とするMYSQLテーブルがある。今日の日付から数年後までのデータがあります。より高速な照会のために、私は古いレコードを検索する必要がないので、通常、古いレコードを削除します。しかし、分析のために必要な場合は、私はまだレコードのバックアップコピーを保持しています。元のテーブルはこれです:mysqlテーブルから古いレコードを削除するが、バックアップを保持する

CREATE TABLE featured_deal (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
     fsa VARCHAR(10), 
     poster_id int(11), 
     dealid bigint(20), 
     bookedDate date, 
     createDate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    UNIQUE KEY `featured_unique`(fsa, bookedDate) 
    ) 

そして私は、この表のレプリカであるテーブルを作成する歴史と呼ばれる:挿入は上が起こるたび

CREATE TABLE featured_deal_history (
      id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
       fsa VARCHAR(10), 
       poster_id int(11), 
       dealid bigint(20), 
       bookedDate date, 
       createDate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
      UNIQUE KEY `featured_unique`(fsa, bookedDate) 
      ) 

は、私は歴史の表を移入するトリガーを持っています元のテーブル:

CREATE TRIGGER `featured_to_history` 
      AFTER INSERT ON lst_enmasse_featured_deal 
      FOR EACH ROW 
      INSERT INTO lst_enmasse_featured_deal_history (fsa,poster_id,dealid,bookedDate,createDate) 
      VALUES (NEW.fsa,NEW.poster_id,NEW.dealid,NEW.bookedDate,NEW.createDate) 

最後に、私はcronジョブやコマンドを使用して、テーブルをきれい:

DELETE * FROM featured_deal WHERE bookedDate < DATE_SUB(CURDATE(), INTERVAL 30 DAY) 

上記のタスクを実行するより良い方法はありますか?私はMYSQLパーティションについて考えました。しかし、私は固定パーティションを持っていません。日付が変わるので、毎日2つの新しいパーティションが必要になります。

答えて

1

原則として、aproachは問題ありませんが、概念がより小さなテーブルがより効率的であるという考えに基づいています。これは、クエリに対してデータに対する完全なテーブルスキャンが実行されていることを意味します。つまり、インデックスを正しく設定していません。

最初に修正するのは、クエリのパフォーマンスです。

ホットデータテーブルからデータを取り除く必要がある場合は、一度に一括ではなく一括操作として履歴テーブルに挿入する必要があります。これは、テーブルとインデックスを健全に保ちます状態。これは、Cristianによって提案されたバッチ操作で実行できます。または、(ソーステーブルに状態変数を持つ)確率的な方法を使用できます。例えば何かのようなもの...

AFTER INSERT ON mytable 
IF (0.95<RAND()) THEN 
    UPDATE mytable SET control=CONNECTION_ID() 
    WHERE control IS NULL; 
    INSERT INTO backuptable (...) 
    SELECT .... FROM mytable 
    WHERE control=CONNECTION_ID(); 
    UPDATE mytable SET control=-1 
    WHERE control=CONNECTION_ID(); 
END IF; 

さらなるヒントは、履歴テーブルに書き込むときに新しいIDを生成することです。なぜですか?

+0

私は実際に目的に役立たなかったので、新しいIDを履歴テーブルから削除しました。 –

0

私はそれを簡単にします。 「TODAY_DATE」でこれら2 queryesを実行し、毎日のcronを作成します。どうなる

create table if not exists featured_deal_new like featured_deal 
rename table featured_deal to featured_deal_history_TODAY_DATE, featured_deal_new to featured_deal 

:(テーブルの名前を変更することは非常に高速です)。毎日の履歴表があります。

その後

insert into featured_deal_history... select * from featured_deal_history_TODAY_DATE

Drop table featured_deal_history_TODAY_DATE 

あなたがメインテーブルでの挿入に緩んでパフォーマンスをしないでください。この道を履歴テーブルを結合すること自由に感じなさい。

関連する問題