3

数億のレコードで埋められる分割テーブルを作成したいと考えています。パーティショニングを使用して、特定の日のレコードを 1 つのパーティションに入れ、翌日のレコードを別のパーティションに入れるにはどうすればよいでしょうか。その後、90 日後に古いデータを最も古いパーティションから削除できます。

私はこの宣言を試みました (ハッシュ関数はパーティションの量に対してモジュロを使用して、どのパーティションがデータを取得するかを計算します)。これにより、毎日が 92 個のパーティションの異なる 1 つを使用することが保証されます。それが機能しないことを除いて。

CREATE TABLE records(
    id INT NOT NULL AUTO_INCREMENT,
    dt DATETIME,
    PRIMARY KEY (id)
)
PARTITION BY HASH((MOD(DAYOFYEAR(dt), 92) + 92))
PARTITIONS 92;

上記のスニペットの問題は、ハッシュ式で使用される列がテーブル内で一意のキーでなければならないことです。

毎日の記録に基づいて 90 個のローテーション パーティションを作成するにはどうすればよいですか?

単にdt列を主キーに追加すると、日付範囲を選択するとすべてのパーティションにヒットするように見えますが、これは私が望むものではありません。

何か案は?

4

2 に答える 2

2

その理由は、日付フィールドでパーティション化し、範囲でクエリを実行するには、パーティション式でYEAR()またはを使用する必要があるためです。TO_DAYS()

このようなパーティショニングは期待どおりに機能します。

CREATE TABLE `alert` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `eventId` int(10) unsigned NOT NULL,
  `occurred` datetime NOT NULL,
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
/*!50100 PARTITION BY RANGE (TO_DAYS(occurred))
(PARTITION 28_06 VALUES LESS THAN (735413) ENGINE = InnoDB,
 PARTITION 29_06 VALUES LESS THAN (735414) ENGINE = InnoDB,
 PARTITION 30_06 VALUES LESS THAN (735415) ENGINE = InnoDB,
 PARTITION 01_07 VALUES LESS THAN (735416) ENGINE = InnoDB,
 PARTITION 02_07 VALUES LESS THAN (735417) ENGINE = InnoDB,
 PARTITION 03_07 VALUES LESS THAN (735418) ENGINE = InnoDB,
 PARTITION 04_07 VALUES LESS THAN (735419) ENGINE = InnoDB,
 PARTITION 05_07 VALUES LESS THAN (735420) ENGINE = InnoDB,
 PARTITION 06_07 VALUES LESS THAN (735421) ENGINE = InnoDB,
 PARTITION 07_07 VALUES LESS THAN (735422) ENGINE = InnoDB) */

mysql> explain partitions SELECT * FROM alert WHERE occurred >= '2013-07-02' and occurred <= '2013-07-04';
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | partitions        | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | alert | 02_07,03_07,04_07 | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+

次に、パーティションの削除と作成を自分で管理する必要があります。

于 2013-06-28T11:59:50.037 に答える
0

実際には、問題は、キーのすべての列がハッシュ関数に含まれていない場合、分割されたテーブルで PRIMARY または UNIQUE キーを定義できないことです。

考えられる「修正」の 1 つは、「PRIMARY」キーワードを KEY 定義から削除することです。

問題は、キーを UNIQUE または PRIMARY として宣言するときに、MySQL が一意性を強制する必要があることです。そしてそれを強制するために、MySQL はキー値がすでに存在するかどうかをチェックできる必要があります。すべてのパーティションをチェックする代わりに、MySQL はパーティショニング機能を使用して、特定のキーが見つかるパーティションを決定します。

于 2013-06-27T20:55:15.550 に答える