Оптимизация селекта.

  • Автор темы Автор темы cDLEON
  • Дата начала Дата начала

cDLEON

Онанист РНРСlub
Оптимизация селекта.

[sql]
CREATE TABLE `antiLeech_partnerPayments` (
`kid` bigint(20) NOT NULL,
`pid` int(11) NOT NULL,
`type` int(2) NOT NULL,
`summ` decimal(10,2) NOT NULL,
`aType` int(2) default NULL,
`aValue` decimal(10,2) default NULL,
`psumm` decimal(10,2) NOT NULL,
`paided` int(1) NOT NULL,
`time` int(11) NOT NULL,
KEY `pid` (`pid`,`time`),
KEY `kid` (`kid`),
KEY `pid_2` (`pid`),
KEY `paided` (`paided`,`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
[/sql]
[sql]SELECT p.id, p.login, p.lastPaidTime, p.paided, sum( pay.psumm ) as psumm , max( pay.`time` ) as lasttime
FROM antiLeech_partners AS p, antiLeech_partnerPayments AS pay
WHERE p.id >0
AND pay.paided =0
AND pay.pid = p.id
GROUP BY pay.pid
LIMIT 0,15
[/sql]
Вторую таблицу сбрасывать не стал, т.к. там селект идёт по примаку.
Вот решил потестить запросы...40 партнёров, у каждого по 10 000 "платежей". Запрос выполняется довольно долго (4.5 сек), за счёт того, что селект проходит 399 997 записей, хотя по логике вещей, он должен был взять только 15*10 000. Что я делаю не так? Как оптимизировать?
ЗЫ. поиск идёт по индексу paided.
 
fixxxer
Сори...Вот:
Код:
id	select_type	table	type	possible_keys		key  	key_len	ref			rows  Extra  
1	SIMPLE     	pay 	range	pid,pid_2,paided 	paided	8 	NULL 			399996 Using where 
1	SIMPLE 		p 	eq_ref	PRIMARY 		PRIMARY	4 	antileech.pay.pid 	1

-~{}~ 04.02.08 07:30:

это я так отбрасываю "системные" данные.
 
имхо таблицы должны джоиниться в другом порядке. Этому может мешать GROUP BY pay.pid вместо GROUP BY p.id
 
Этому может мешать GROUP BY pay.pid вместо GROUP BY p.id
Так оно и есть...Только теперь проходятся все записи из таблицы partners а что если их тоже будет 10 000 ? (
Получается...Нужно выкинуть GROUP BY...Но тогда считать сумму столбцов не получится...
имхо таблицы должны джоиниться в другом порядке.
всмысе? как мне вывести первые 15 партнёров, начиная с таблицы с "платежами" ? Тогда ведь сто пудофф придётся делать группировку по пиду...А это херова туча записей))
 
Так оно и есть...
пока что я вижу только GROUP BY pay.pid. А нужен там GROUP BY p.id.

А остаток твоего сообщения я вообще не понял.

-~{}~ 04.02.08 11:48:

имхо таблицы должны джоиниться в другом порядке.
Я имел в виду, что должно быть как-то типа
Код:
id	select_type	table	type	possible_keys		key  	key_len	ref			rows  Extra  
1	SIMPLE 		p 	                    ...                                           	15  
1	SIMPLE     	pay 	                    ...                             			10000
вместо того, что у тебя сейчас выводится в explain'е.
 
"Так оно и есть" всмысле что действительно, мешает этот групбай ))
Кстати... Время селекта уменьшилось, но не на столько, на сколько хотелось...Теперь 3 сек....И ещё. Игнорируется индекс "paided" =(
А хотелось бы, что б селект и его использывал...Пробывал играться с созданием индексов...Игнорирует всё, кроме индекса только с ПИДом.
Код:
id	select_type	table	type	possible_keys		key  	key_len	ref		rows	Extra  
1	SIMPLE		p 	range	PRIMARY 		PRIMARY	4 	NULL		41 	Using where 
1	SIMPLE		pay	ref	pid,pid_2,paided	pid_2	4 	antileech.p.id	10000	Using where

-~{}~ 04.02.08 08:54:

А ну...Так оно и есть...Просто я из ПХПмайдамина вытягиваю...
И в блокноте форматирование выставляю))
 
Кстати... Время селекта уменьшилось, но не на столько, на сколько хотелось...Теперь 3 сек....И ещё. Игнорируется индекс "paided" =(
давай ты просто будешь кидать новые запросы и новые explain'ы? :)

А ну...Так оно и есть...Просто я из ПХПмайдамина вытягиваю...
И в блокноте форматирование выставляю))
и причем тут phpmyadmin и блокнот?!
 
Запрос не изменилсо практически))
Эксплайн выше))
А phpmyadmin и блокнот связаны тем, что результат эксплайна я выдёргиваю оттуда, закидываю в блокнот и расставляю там табы что бы закинуть сюда :D
 
если кол-во записей с `paided` = 0 составляет довольно маленький процент от всех, то попробуй добавить индекс ( `pid`, `paided` ).

-~{}~ 04.02.08 12:07:

Игнорируется индекс "paided" =(
вообще, логично :)
 
Wicked
если кол-во записей с `paided` = 0 составляет довольно маленький процент от всех
А вот этого я обещать не могу(
Кстати. Не знаю что я делал раньше не так, но вроде теже действия действовали только хуже...
Кстате...Ни у кого проблем с плагином к экллипсу не было? А то я не могу добавить новый коннект...Селект с драйверами полностью пустой, а при нажатии на Add\Edit drivers их там целая куча=(
ЗЫ. SQLExplorer юзаю.
ЗЫ.ЗЫ. На данный момент селект идёт 2.8 сек...
 
сначала оптимизируй выборки из каждой таблицы по отдельности
потом джойни учитывая то что группировку-ордер надо делать по первой таблице чтобы не было using filesort/temporary (тут иногда может помочь straight_join - обычно mysql выбирает порядок минимизируя rows, но вариант с "чуть больше" rows без filesort быстрее). ну и учитывай что mysql<5 может использовать только один индекс, >=5 умеет в некоторых случаях использовать несколько и делать объединение но этого все равно лучше избегать
 
fixxxer
сначала оптимизируй выборки из каждой таблицы по отдельности
это, как правило, работает только для первой таблицы из предположительного плана запроса :) а принимая во внимание, что план запроса - довольно изменчив (при изменении индексов, запроса в пределах эквивалентности), то я очень сомневаюсь, что такой подход будет работать.
 
ну смотря о чем идет речь, смотреть как используются индексы при каких условиях в where удобно отдельно (лично мне по крайней мере), а все о чем ты говоришь разумеется надо учитывать =)
 
Толи туплю, толи тупой...
Не могу получить количество удовлетворяющее данным критериям....Хочу разделить по страницам...Но, не извлекать все данные сразу.
Есть одна сложность - мне нужны партнёры, у которых есть хотя бы одна выплата.
 
Сверху