1

日付に基づいてパーティションを構成しようとしましたが、mysql にはまだ関連データのないパーティションが含まれているようです。関連するパーティションが使用されますが、何らかの理由で最も古いパーティションも含まれます。私はそれを間違っていますか?

バージョンは 5.1.44 (MyISAM)

最初に、「日付」タイプの「日」に基づいていくつかのパーティションを追加しました

ALTER TABLE ptest
PARTITION BY RANGE(TO_DAYS(day))
(
PARTITION p1 VALUES LESS THAN (TO_DAYS('2009-08-01')),
PARTITION p2 VALUES LESS THAN (TO_DAYS('2009-11-01')),
PARTITION p3 VALUES LESS THAN (TO_DAYS('2010-02-01')),
PARTITION p4 VALUES LESS THAN (TO_DAYS('2010-05-01'))
);

クエリの後、関連するデータが含まれていないはずの「古い」パーティションが使用されていることがわかりました。

mysql> explain partitions select * from ptest where day between '2010-03-11' and '2010-03-12';
+----+-------------+------------+------------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------+------------+-------+---------------+------+---------+------+------+-------------+
| 1  | SIMPLE      | ptest      | p1,p4      | range | day           | day  | 3       | NULL | 79   | Using where |
+----+-------------+------------+------------+-------+---------------+------+---------+------+------+-------------+

1 日を選択すると、期待どおりに動作します。

mysql> explain partitions select * from ptest where day = '2010-03-11';
+----+-------------+------------+------------+------+---------------+------+---------+-------+------+-------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref   | rows | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+-------+------+-------+
| 1  | SIMPLE      | ptest      | p4         | ref  | day           | day  | 3       | const | 39   |       |
+----+-------------+------------+------------+------+---------------+------+---------+-------+------+-------+
4

2 に答える 2

2

最も古いパーティションは、有効な日付 (null) に評価されなかった値を常に保持するため、これは実際には意図した結果です。これを回避するには、データを保持せず、最も古い日付より前のすべての値に対して存在する追加のパーティションを作成します。このパーティションは常にスキャンされますが、空であるためパフォーマンスへの影響はほとんどありません。

http://bugs.mysql.com/bug.php?id=49754

于 2011-06-21T00:31:50.420 に答える
1

TO_DAYS(date) でパーティション分割しました。つまり、制約に TO_DAYS(date) を適用しない限り、ほとんどの場合、パーティション分割のプルーニングは単純なケースでのみ発生します。

たとえば select * from ptest where day between TO_DAYS('2010-03-11') と TO_DAYS('2010-03-12') を実行する必要があります。

mysql での日付のパーティション化は難しく、パーティション化の実装には多くの欠点があります。少なくとも、さまざまなクエリの制約をカバーしたい場合は、通常、DATE 型ではなくカレンダーを指す整数 ID をテーブルに配置します。 、関数 (TO_DAYS など) を含む列でのパーティション分割と比較して、単純な整数でのパーティション分割を処理する mysql が非常に信頼性が高いことがわかりました。

create table datatbl (
  time_id int NOT NULL,
  ....
);

time_id は、次の 10 年間の日付が事前に入力されたカレンダーを参照します。

create table calendar (
  time_id int primary key
  year int NOT NULL,
  month int NOT NULL,
  day int NOT NULL,
  dayofyear int NOT NULL,
  quarter int NOT NULL,
  is_weekend char(1) NOT NULL,
  db_date DATE not NULL,
  unique index(year,month,day),
  unique index(dbdate)
);

クエリはこのテーブルに結合されるため、1 か月分のすべてのデータを取得するにはwhere cal.year = 2010 and cal.month = 1. または、次のように行うこともできますcal.db_date between '2010-01-01' and '2010-01-31'

datatblは time_id でパーティション化されており、上記のクエリにより、mysql はパーティショニング プルーニングを実行します。time_id も年/月/日の複合であるため、2010-03-03 の time_id は整数 20100303 になります。これは、クエリに使用しないでください。これは、新しい/ドロップを自動的に作成するスクリプトにとって単に便利です。古いパーティション。

于 2010-03-19T10:19:44.850 に答える