Мне нужно посмотреть все мои товары (sku's), их последнее количество на складе.
У меня есть одна таблица (называемая «сток») с 315 тысячами записей +, содержащих эту информацию (каждый день добавляется новый пакет данных для большинства sku) Справочные данные находятся в другой таблице (называемой «складской файл»).
Это запрос для этого:
SELECT s1 . * , f1 . *
FROM stock s1
JOIN stockfile f1 ON ( s1.stockfileid = f1.stockfileid )
LEFT OUTER JOIN ( stock s2
JOIN stockfile f2 ON ( s2.stockfileid = f2.stockfileid )
) ON ( s1.sku = s2.sku
AND ( f1.date < f2.date
OR f1.date = f2.date
AND f1.stockfileid < f2.stockfileid) )
WHERE s2.sku IS NULL
Это определения таблиц
SHOW CREATE TABLE
акции:
CREATE TABLE `stock` (
`stockid` bigint(20) NOT NULL AUTO_INCREMENT,
`sku` char(25) NOT NULL,
`quantity` int(5) NOT NULL,
`creationdate` datetime NOT NULL,
`stockfileid` smallint(5) unsigned NOT NULL,
`touchdate` datetime NOT NULL,
PRIMARY KEY (`stockid`),
KEY `stock_sku` (`sku`),
KEY `stock_stockfileid` (`stockfileid`)
) ENGINE=MyISAM AUTO_INCREMENT=316039 DEFAULT CHARSET=latin1
SHOW CREATE TABLE
склад:
CREATE TABLE `stockfile` (
`stockfileid` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`filename` varchar(25) NOT NULL,
`creationdate` datetime DEFAULT NULL,
`touchdate` datetime DEFAULT NULL,
`date` datetime DEFAULT NULL,
`begindate` datetime DEFAULT NULL,
`enddate` datetime DEFAULT NULL,
PRIMARY KEY (`stockfileid`),
KEY `stockfile_date` (`date`)
) ENGINE=MyISAM AUTO_INCREMENT=266 DEFAULT CHARSET=latin1
Без каких-либо дополнительных индексов это займет ... навсегда. Я добавил их, и они ускорились примерно до 250 секунд:
CREATE INDEX stock_sku ON stock(sku);
CREATE INDEX stock_stockfileid ON stock(stockfileid);
CREATE INDEX stockfile_date ON stockfile(date);
Это EXPLAIN
в исходном запросе с этими индексами.
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE s1 ALL stock_stockfileid NULL NULL NULL 316038
1 SIMPLE f1 eq_ref PRIMARY PRIMARY 2 kompare.s1.stockfileid 1
1 SIMPLE s2 ref stock_sku,stock_stockfileid stock_sku 25 kompare.s1.sku 12 Using where
1 SIMPLE f2 eq_ref PRIMARY,stockfile_date PRIMARY 2 kompare.s2.stockfileid 1
Есть ли другой способ ускорить процесс?
- Спасибо Биллу Карвину за решение оригинального запроса!