Обрезка подразделов MYSQL - PullRequest
1 голос
/ 08 декабря 2011

У меня есть таблица MYSQL с разделом на год и подразделом на месяц.

CREATE TABLE ptable (
   id INT NOT NULL AUTO_INCREMENT, 
   name varchar(100),
   purchased DATETIME NOT NULL,
   PRIMARY KEY (id, purchased)
)

PARTITION BY RANGE( YEAR(purchased) )
SUBPARTITION BY HASH( MONTH(purchased) )
SUBPARTITIONS 12 (
   PARTITION p0 VALUES LESS THAN (2011),
   PARTITION p1 VALUES LESS THAN (2012),
   PARTITION p5 VALUES LESS THAN MAXVALUE
);

Большинство моих запросов к этой таблице связаны с указанием года или месяца. Когда я пытаюсь выполнить запрос по месяцам, он не выполняет надлежащее сокращение и сканирует все 12 подразделов данного года.

explain partitions

SELECT *
FROM ptable
WHERE purchased BETWEEN '2011-12-01' AND '2011-12-31';

Мой вопрос: есть ли способ заставить MYSQL запрашивать только конкретный подраздел, когда я знаю значения года и месяца? Или, может быть, там лучше сделать это. Я использую MYSQL 5.1.

Ответы [ 2 ]

0 голосов
/ 23 августа 2016

Начиная с MySQL 5.6.2, SELECT поддерживает явный выбор разделов с помощью ключевого слова PARTITION со списком разделов или подразделов

Для тех, кто использует более новый MySQL, мы можем использовать SELECT * FROM kit.t1 PARTITION (partition_name [, partition_name] ...); для выбора строк из указанных разделов таблицы (под)

0 голосов
/ 08 декабря 2011

http://dev.mysql.com/doc/refman/5.1/en/partitioning-pruning.html говорит:

Сокращение также может применяться к таблицам, разделенным на столбцы DATE или DATETIME, когда выражение разделения использует функцию YEAR() или TO_DAYS().

В MySQL 5.5 они добавили TO_SECONDS() к еще очень короткому списку функций, которые MySQL достаточно умен, чтобы использовать для сокращения раздела.

Так что вы должны иметь возможность подрезать подраздел для работы с:

SUBPARTITION BY HASH( TO_DAYS(purchased)/30 )

Вы по-прежнему можете использовать 12 подразделов, вы просто обнаружите, что данные каждого месяца не будут точно совпадать с подразделами. Но он подрежет, когда сможет.

Альтернативой может быть добавление еще одного столбца в вашу таблицу, например, purchased_month TINYINT UNSIGNED и сохраните значение MONTH(purchased) в этом столбце с избыточностью. Затем используйте его в качестве ключа подразделения:

SUBPARTITION BY HASH( purchased_month )
...