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

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.
 

cDLEON

Онанист РНРСlub
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:

это я так отбрасываю "системные" данные.
 

Wicked

Новичок
имхо таблицы должны джоиниться в другом порядке. Этому может мешать GROUP BY pay.pid вместо GROUP BY p.id
 

cDLEON

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

Wicked

Новичок
Так оно и есть...
пока что я вижу только 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'е.
 

cDLEON

Онанист РНРСlub
"Так оно и есть" всмысле что действительно, мешает этот групбай ))
Кстати... Время селекта уменьшилось, но не на столько, на сколько хотелось...Теперь 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:

А ну...Так оно и есть...Просто я из ПХПмайдамина вытягиваю...
И в блокноте форматирование выставляю))
 

Wicked

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

А ну...Так оно и есть...Просто я из ПХПмайдамина вытягиваю...
И в блокноте форматирование выставляю))
и причем тут phpmyadmin и блокнот?!
 

cDLEON

Онанист РНРСlub
Запрос не изменилсо практически))
Эксплайн выше))
А phpmyadmin и блокнот связаны тем, что результат эксплайна я выдёргиваю оттуда, закидываю в блокнот и расставляю там табы что бы закинуть сюда :D
 

Wicked

Новичок
если кол-во записей с `paided` = 0 составляет довольно маленький процент от всех, то попробуй добавить индекс ( `pid`, `paided` ).

-~{}~ 04.02.08 12:07:

Игнорируется индекс "paided" =(
вообще, логично :)
 

cDLEON

Онанист РНРСlub
Wicked
если кол-во записей с `paided` = 0 составляет довольно маленький процент от всех
А вот этого я обещать не могу(
Кстати. Не знаю что я делал раньше не так, но вроде теже действия действовали только хуже...
Кстате...Ни у кого проблем с плагином к экллипсу не было? А то я не могу добавить новый коннект...Селект с драйверами полностью пустой, а при нажатии на Add\Edit drivers их там целая куча=(
ЗЫ. SQLExplorer юзаю.
ЗЫ.ЗЫ. На данный момент селект идёт 2.8 сек...
 

fixxxer

К.О.
Партнер клуба
сначала оптимизируй выборки из каждой таблицы по отдельности
потом джойни учитывая то что группировку-ордер надо делать по первой таблице чтобы не было using filesort/temporary (тут иногда может помочь straight_join - обычно mysql выбирает порядок минимизируя rows, но вариант с "чуть больше" rows без filesort быстрее). ну и учитывай что mysql<5 может использовать только один индекс, >=5 умеет в некоторых случаях использовать несколько и делать объединение но этого все равно лучше избегать
 

Wicked

Новичок
fixxxer
сначала оптимизируй выборки из каждой таблицы по отдельности
это, как правило, работает только для первой таблицы из предположительного плана запроса :) а принимая во внимание, что план запроса - довольно изменчив (при изменении индексов, запроса в пределах эквивалентности), то я очень сомневаюсь, что такой подход будет работать.
 

fixxxer

К.О.
Партнер клуба
ну смотря о чем идет речь, смотреть как используются индексы при каких условиях в where удобно отдельно (лично мне по крайней мере), а все о чем ты говоришь разумеется надо учитывать =)
 

cDLEON

Онанист РНРСlub
Толи туплю, толи тупой...
Не могу получить количество удовлетворяющее данным критериям....Хочу разделить по страницам...Но, не извлекать все данные сразу.
Есть одна сложность - мне нужны партнёры, у которых есть хотя бы одна выплата.
 
Сверху