Эти тесты проводились в: php 5.4 / MySql 5.5.42 Dual SSD Raid-1.
Резервирование столов с почти 2 миллионами записей и неделями (более 2 миллионов записей, потому что некоторые заказы охватывают более 2 недель)
CREATE TABLE `bookings` (
`id` int(11) NOT NULL AUTO_INCREMENT, ## id is booking number.
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
/* . . . . . . Rest of booking's info */
PRIMARY KEY (`Id`),
KEY `st_end` (`start_date, end_date`),
KEY `end_date` (`end_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='A record for each booking';
CREATE TABLE `weeks` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`bk_nr` int(11) DEFAULT NULL,
`week` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `week` (`week`),
KEY `bk_nr` (`bk_nr`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
COMMENT='Records indicate that booking (bk_nr) touches week number (week)';
Each booking may have several records in "weeks". One for each week that it touches.
Неделя была создана на php с использованием даты («oW»). Он создает год-неделю, например: для 2015-03-01: 201509 (2015 год, неделя 09).
Результаты теста. Поиск бронирований, использующих любой день марта 2015 года. Сначала худшее.
0,56 секунды
SELECT DISTINCT c.* FROM bookings c
WHERE c.d_start_date <= "2015-03-31" AND c.d_end_date >= "2015-03-01"
AND c.id in (
SELECT w.bk_nr FROM weeks w
WHERE w.week between 201509 AND 201514
);
0,14 секунды
SELECT DISTINCT c.* FROM bookings c, weeks w
WHERE c.id = w.bk_nr
AND w.week between 201509 AND 201514
AND c.d_start_date <= "2015-03-31" AND c.d_end_date >= "2015-03-01";
И победителем становится . . . .
Лучшее: 0,1 секунды
SELECT DISTINCT * FROM bookings
WHERE start_date <= "2015-03-31" AND end_date >= "2015-03-01";
Похоже, MySql улучшился по сравнению с моими предыдущими тестами (выполненными в mysql 4.x), и теперь он знает, как эффективно обрабатывать этот тип запросов.
Не нужно этому помогать. (Время измерялось простым "SELECT now ()" до и после каждого запроса.) Спасибо, Рик Джеймс, за вашу помощь.
person
Rafael
schedule
14.05.2015