2010-05-31 1 views
1

У меня есть следующий запрос, который составляет 3 секунды на столе из 1500 строк, кто-то знает, как его упростить?Мне нужно упростить подзапрос MySQL для производительности - пожалуйста, помогите

SELECT dealers.name, dealers.companyName, dealer_accounts.balance 
FROM dealers 
    INNER JOIN dealer_accounts 
    ON dealers.id = dealer_accounts.dealer_id 
WHERE dealer_accounts.id = (
    SELECT id 
    FROM dealer_accounts 
    WHERE dealer_accounts.dealer_id = dealers.id 
    AND dealer_accounts.date < '2010-03-30' 
    ORDER BY dealer_accounts.date DESC, dealer_accounts.id DESC 
    LIMIT 1 
) 
ORDER BY dealers.name 

мне нужна последняя dealer_accounts запись для каждого дилера по определенной дате объединения на dealer_id поле на столе dealer_accounts. Это действительно должно быть просто, я не знаю, почему я изо всех сил пытаюсь найти что-то.

+0

Является ли 'DEALER_ACCOUNTS.id' автоинкремент? И возможно ли, чтобы «DEALER_ACCOUNT» имел значение «date date» с обратной связью? В противном случае 'MAX (dealer_accounts.id)' должно быть хорошо. –

+0

Спасибо за ваш комментарий, однако даты могут быть добавлены не в порядке, в противном случае ваше предложение сработало бы. Спасибо за помощь! – Richard

ответ

0

Вы можете попробовать использовать два запроса вместо одного, т. Е. Получить идентификатор и использовать это вместо подзапроса. Это может сказать вам, какой из запросов медленный. Также я считаю, что MySQL будет кэшировать отдельные запросы, ускоряя несколько запросов.

У вас есть индексы на таблицах? в общем, вы должны индексировать любые столбцы, которые вы фильтруете или сортируете. В вашем примере, конечно, будет столбец dealer_accounts.date.

Я предполагаю, что поля идентификатора являются первичными ключами, если это так, бессмысленно добавлять dealer_accounts.id к критериям сортировки.

+0

Я действительно хотел посмотреть, не хватает ли я очевидного, выясняется, что вопрос не слишком уж плох, все, что я хочу, это последняя учетная запись, поэтому я думал, что будет более простой способ сделать это. Но ваша точка в индексировании была права, я изменил db на innodb и добавил индекс на dealer_id и получил его до 302 мс, хотя, хотя это и не удивительно быстро, он по-прежнему вполне разумен и в 10 раз быстрее, чем у меня. Еще раз спасибо за вашу помощь – Richard

0

Я не знаю, почему вы не можете просто сделать это:

SELECT 
    dealers.name, dealers.companyName, dealer_accounts.balance 
FROM 
    dealers, dealer_accounts 
WHERE 
    WHERE dealer_accounts.dealer_id = dealers.id 
    AND dealer_accounts.date < '2010-03-30' 
ORDER BY dealer_accounts.date DESC, dealer_accounts.id DESC 

Попробуйте MySQL EXPLAIN PLAN на запросе. Если вы видите TABLE SCAN, вот почему ваш запрос настолько медленный.

Я не знаю, какие индексы у вас есть на ваших таблицах, но, возможно, это поможет добавить соответствующие. ПЛАН EXPLAIN может рассказать вам, где им не хватает.

+0

К сожалению, синтаксис в вашем примере неверен, но ваш поясняющий совет был полезен для будущей справки. Я сам до сих пор не знаю, почему GROUP BY dealer_id ORDER BY date DESC, id DESC не будет отображать последнюю учетную запись. Но мне удалось ускорить его до приемлемого уровня, переключившись на innodb и indexing dealer_id. Еще раз спасибо за вашу помощь – Richard

0

Ваш подзапрос работает много раз, и я подозреваю, что у вас нет индексов на dealer_accounts.date и dealer_accounts.dealer_id. Вы должны обязательно посмотреть на необходимость фильтрации в статическом поле в вашем подзапросе. Должна быть возможность фильтрации на дату один раз, а затем выполнить подзапрос на меньшем наборе.

+0

Я думаю, что вы правы в подзапросе и времени. Что касается фильтрации, я думаю, что вы снова правы, но я не хотел вникать в это, так как это усложняло бы его немного больше. Но, действительно, изменив его на innodb и добавив индекс на dealer_id, он ускорил его 10 раз! Я доволен этим ... Спасибо за вашу помощь – Richard