Оптимизация запроса

BMWX6

AG епты
Имеем в итоге

Код:
SELECT term.termid, SUM(term.elp) AS elp, SUM(term.elw) AS elw, SUM(term.elf) AS elf FROM term, users, termn 
WHERE term.termid = termn.id AND termn.user_id IN (1,2,3,...104,105,106) AND termn.user_id = users.id 
AND term.dates >= '2013-05-01 00:00:00' AND term.dates <= '2013-05-28 23:59:59' GROUP BY term.termid
записей в таблице term около 5 млн, запрос обрабатывается около 12 сек, что будет дальше ....
помогите оптимизировать или нереально не раскидывая данные по разным машинам такое оптимизировать?
Заранее спасибо.
 

BMWX6

AG епты
Код:
Field 	Type 	Null 	Key 	Default 	Extra
id 	bigint(20)	NO 	MUL 	NULL	auto_increment
termid 	bigint(20)	NO 	MUL 	NULL	
dates 	datetime	NO 	MUL 	NULL	
gameid 	int(4)	NO 		NULL	
elp 	        float(10,2)	NO 		NULL	
elw	        float(10,2)	NO 		NULL	
elf      	int(1)	NO 		NULL
 

BMWX6

AG епты
Код:
id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra
1 	SIMPLE 	term 	ALL 	termid,dates 	NULL	NULL	NULL	5191857 	Using where; Using temporary; Using filesort
1 	SIMPLE 	termn 	ref 	id 	id 	8 	lt.term.termid 	1 	Using where
1 	SIMPLE 	users 	ref 	id 	id 	8 	lt.termn.user_id 	3119 	Using index
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Как минимум, на dates нужно отдельный индекс.
 

Фанат

oncle terrible
Команда форума
ну вот смотри - тебе пишет здесь, что индекс не используется, хотя найдено два вероятных.
я не очень хорошо понимаю эту кухню, но думаю, что в лоб можно добиться ускорения, насильно заставив использовать индекс по дате,
PHP:
SELECT ... FROM term FORCE INDEX(dates), users, termn
сделать explain extended и потом show warnings - и посмотреть, что из твоего запроса сделала база перед выполнением

И я бы сначала упростил запрос, убрав из него джойны и посмотрел - если проблема остается, то и тренировался бы только на term, пока не добился бы стабильной быстрой выборки. Потому что два джойна, как видно из екплейна, отрабатывают мгновенно
 

BMWX6

AG епты
Код:
Действие	Имя индекса	Тип	Уникальный	Упакован	Столбец	Уникальных элементов	Сравнение	Null	Комментарий
 Удалить Удалить 	id	        BTREE	Нет	Нет	id	5191857	A	Нет	
 Удалить Удалить 	termid       BTREE	Нет	Нет	termid	511	A	Нет	
 Удалить Удалить 	dates	        BTREE	Нет	Нет	dates	    200	A	Нет
не оно?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Кстати, я сначала не заметил:
WHERE IN ... — медленная штука. Очень.
 

Фанат

oncle terrible
Команда форума
Кстати, я сначала не заметил:
WHERE IN ... — медленная штука. Очень.
Вот фигу там.
Есть какие-то маргинальные случаи, но вообще обычно очень быстро работает.

А вот что реально надо сделать - это джойнить две другие таблицы к ЮЗЕРАМ, которых всего сотня.

BMWX6 попробуй переписать запрос, указывая джойны явно, и поставь юзеров первыми
 

Фанат

oncle terrible
Команда форума
вру. талица юзеров здесь вообще, вроде, не нужна.
джойнь termn на term
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Вот фигу там.
Есть какие-то маргинальные случаи, но вообще обычно очень быстро работает.
Чисто из интереса, попробуй выполнить:

PHP:
SELECT term.termid, SUM(term.elp) AS elp, SUM(term.elw) AS elw, SUM(term.elf) AS elf FROM term, users, termn 
WHERE term.termid = termn.id AND termn.user_id < 106 AND termn.user_id = users.id 
AND term.dates >= '2013-05-01 00:00:00' AND term.dates <= '2013-05-28 23:59:59' GROUP BY term.termid
Будет ли разница по скорости в плане запроса?
 

Фанат

oncle terrible
Команда форума
Будет ли разница по скорости в плане запроса?
Мне кажется, что нет.
основные же тормоза из-за фуллскана по term.
Имхо, найти сотню юзеров и для них найти по первичному соответствия в терм получится быстро хоть тушкой, хоть чучелком.
 

BMWX6

AG епты
переехал с medium на xlarge (amazon RDS), выйграл во времени в 3-и раза, правда в цене ровно в 3-и раза програл. Время равно деньги ))
 
Сверху