Выбор раздела MySQL не оптимизирован правильно - PullRequest
1 голос
/ 04 ноября 2011

У меня есть таблица 'fvs_data' со столбцом метки времени, который я использовал для раздела.Оптимизатор запросов, похоже, не выбирает правильные разделы, если у меня сложный запрос.Например, этот запрос

EXPLAIN PARTITIONS SELECT * FROM `fvs_data` WHERE `timestamp` = '2011-11-02'

использует правильный раздел, как показано в списке разделов: p_2011_44, так как TO_DAYS ('2011-11-02') = 734808.

Но еслидобавьте еще одно условие, которое должно возвращать точно такой же раздел, затем он хочет проверить один из других разделов

EXPLAIN PARTITIONS SELECT * FROM `fvs_data` WHERE `timestamp` > '2011-11-01' AND `timestamp` < '2011-11-03'

, который возвращает p_2011_42, p_2011_44 для списка разделов.Вот мой синтаксис CREATE TABLE

CREATE TABLE `fvs_data` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `fvs_client_id` int(11) NOT NULL,
 `timestamp` datetime NOT NULL,
 `setupid` char(20) NOT NULL,
 `assyline` char(20) NOT NULL,
 `machine` char(20) NOT NULL,
 `side` char(20) NOT NULL,
 `module` char(20) NOT NULL,
 `fixtureid` char(20) NOT NULL,
 `fixturepos` char(20) NOT NULL,
 `feedpos` char(20) NOT NULL,
 `partnum` char(20) NOT NULL,
 `vendor` char(20) NOT NULL,
 `tid` char(20) NOT NULL,
 `quant` char(20) NOT NULL,
 `status` char(32) NOT NULL,
 `oper` char(20) NOT NULL,
 `lane1` char(20) NOT NULL,
 `lane2` char(20) NOT NULL,
 `sn` char(20) NOT NULL,
 `totalcomp` char(20) NOT NULL,
 PRIMARY KEY (`id`,`timestamp`),
 KEY `fvs_client_id` (`fvs_client_id`),
 KEY `setupid` (`setupid`),
 KEY `assyline` (`assyline`),
 KEY `machine` (`machine`),
 KEY `side` (`side`),
 KEY `module` (`module`),
 KEY `fixtureid` (`fixtureid`),
 KEY `fixturepos` (`fixturepos`),
 KEY `feedpos` (`feedpos`),
 KEY `partnum` (`partnum`),
 KEY `vendor` (`vendor`),
 KEY `tid` (`tid`),
 KEY `status` (`status`),
 KEY `oper` (`oper`),
 KEY `lane1` (`lane1`),
 KEY `lane2` (`lane2`),
 KEY `sn` (`sn`)
) ENGINE=MyISAM AUTO_INCREMENT=36032 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE ( TO_DAYS(timestamp))
(PARTITION p_2011_42 VALUES LESS THAN (734796) ENGINE = MyISAM,
PARTITION p_2011_43 VALUES LESS THAN (734803) ENGINE = MyISAM,
PARTITION p_2011_44 VALUES LESS THAN (734810) ENGINE = MyISAM,
PARTITION p_2011_45 VALUES LESS THAN (734817) ENGINE = MyISAM) */

Я пытаюсь делать еженедельные разделы, но не исходя из реальных недель, начиная с воскресенья, я просто разделил день года на 7 и использовал его для созданияимя раздела.

1 Ответ

0 голосов
/ 04 ноября 2011

Удаление разделов всегда проверяет первый раздел независимо от значений, которые вы ищете. Это связано с тем, что разделение сохраняет значения NULL в первом разделе .

Чтобы обойти это и оптимизировать разбиение диапазона, создайте начальный раздел для значений, меньших, чем те, которые вы обычно храните:

...
PARTITION BY RANGE ( TO_DAYS(timestamp))
(
PARTITION p_0000 VALUES LESS THAN (0) ENGINE = MyISAM, -- NULLs end up here
PARTITION p_2011_42 VALUES LESS THAN (734796) ENGINE = MyISAM,
PARTITION p_2011_43 VALUES LESS THAN (734803) ENGINE = MyISAM,
PARTITION p_2011_44 VALUES LESS THAN (734810) ENGINE = MyISAM,
PARTITION p_2011_45 VALUES LESS THAN (734817) ENGINE = MyISAM
PARTITION p_MAX VALUES LESS THAN MAXVALUE ENGINE = MyISAM
)

Конечно, ваш столбец отметок времени НЕ НЕДЕЙСТВИТЕЛЕН, так что первый раздел будет пустым, и, следовательно, будет очень быстро искать.

P.S .: Вы также должны добавить раздел, чтобы перехватывать любые большие значения вне диапазона любого другого раздела. В противном случае вставка таких строк завершится неудачей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...