2011-03-16 4 views
1
SELECT a.FundIDRecv,a.SubscribeDt, b.FundName, 
(
    SELECT SUM(c.PricePerWeek) 
    FROM tbl_Hive c 
    WHERE c.FundID IN 
    (
     SELECT FundID from tbl_FundStatic 
     WHERE FundID IN 
     (
      SELECT FundIDSend 
      FROM tbl_FundSubscriptions 
      WHERE FundIDRecv = a.FundIDRecv 
      AND SubscribeDt >= subdate(CURDATE(), INTERVAL weekday(CURDATE()) DAY) 
     ) 
     AND UserID = '14' 
    ) 
) as Price 
FROM tbl_FundSubscriptions a, tbl_Hive b 
WHERE a.FundIDRecv = b.FundID 
AND a.SubscribeDt >= subdate(CURDATE(), INTERVAL weekday(CURDATE()) DAY) 
AND a.FundIDRecv IN 
(
    SELECT FundIDRecv 
    FROM tbl_FundSubscriptions 
    WHERE FundIDSend IN (
     SELECT FundID 
     FROM tbl_FundStatic 
     WHERE UserID = '14' 
    ) 
) 
GROUP BY FundIDRecv 

Этот запрос занимает огромное количество времени для извлечения данных.MySQL: оптимизация запросов

Как я могу оптимизировать этот запрос, чтобы заставить его выполнять и получать результаты быстрее, чем это делает?

+0

Зависит. Каковы ваши таблицы и индексы? Это имеет большое значение. –

+0

Сообщает, что должен делать запрос. – Pentium10

+0

Просьба предоставить структуры БД (таблицы/индексы) и план выполнения (пояснить) для вашего запроса – oryol

ответ

3

Заменить свои вложенные элементы на JOIN. Возьмите это, например:

AND a.FundIDRecv IN 
(
    SELECT FundIDRecv 
    FROM tbl_FundSubscriptions 
    WHERE FundIDSend IN (
     SELECT FundID 
     FROM tbl_FundStatic 
     WHERE UserID = '14' 
    ) 
) 

Почему не просто присоединиться к tbl_FundStatic внешнему запросу, как этот

FROM tbl_FundSubscriptions a 
JOIN tbl_FundStatic s ON (a.FundIDSend = s.FundID) 
WHERE s.UserID = '14' 

Конечно, я не знаю, если это все правильно, но это даст вам идея. Кроме того, вы должны избегать вложенных выборок в самом объявлении SELECT. Это лучше, чтобы присоединиться к tbl_FundStatic и затем выберите поля из него

+0

Как это сделать? Можете ли вы предоставить дополнительную информацию о том, как это сделать? Я понятия не имею об этом –

+0

Да, я попробую это. Спасибо за ввод, хотя. –

3

UNTESTED, но это даст вам идти:

SELECT a.fundidrecv, 
     a.subscribedt, 
     b.fundname, 
     SUM(b.priceperweek) AS price 
FROM tbl_fundsubscriptions a 
     JOIN tbl_hive b 
     ON a.fundidrecv = b.fundid 
     JOIN tbl_fundsubscriptions fs 
     ON fs.fundidrecv = a.fundidrecv 
     JOIN tbl_fundstatic fst 
     ON fst.fundid = fs.fundidsend 
      AND fst.userid = '14' 
WHERE a.subscribedt >= SUBDATE(Curdate(), INTERVAL Weekday(Curdate()) DAY) 
GROUP BY a.fundidrecv 

Вы должны добавить индексы на следующие столбцы:

  • (а. fundidrecv, a.subscribedt)
  • (b.fundid)
  • (fs.fundidrecv)
  • (fst.f undid, fst.userid)
+0

Я скоро проверю и вернусь к вам. –

+1

+1 для усилий ... Мне было слишком лениво, чтобы пройти весь путь :-) –

+0

@ Pentuim10: Спасибо за ввод. Я ценю ваши усилия, но SUM (b.priceperweek) показывает неверные данные. Он не показывает ожидаемого результата. –

Смежные вопросы