#mysql #select #where
#mysql #выберите #где-предложение #where-предложение
Вопрос:
У меня есть следующий запрос mysql, который работает правильно, единственная проблема в том, что он действительно медленный. Может ли кто-нибудь подсказать мне, есть ли лучший и быстрый способ выполнить такой запрос??
SELECT
(select sum(tot) FROM NOI_per_order_perf_global WHERE DATE(datte) = DATE(NOW()) AND origin_country = 'fr') as yoofr,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY AND contry = 'fr') as yooyestfr,
(select sum(tot) FROM table1 WHERE yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014 AND contry = 'fr') as yooyesttfr,
(select sum(tot) FROM table1 WHERE MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014 AND contry = 'fr') as yooyestttfr,
(select MAX(datte) FROM table1 WHERE contry = 'fr') as timingfr,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) AND contry = 'de') as yoode,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY AND contry = 'de') as yooyestde,
(select sum(tot) FROM table1 WHERE yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014 AND contry = 'de') as yooyesttde,
(select sum(tot) FROM table1 WHERE MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014 AND contry = 'de') as yooyestttde,
(select MAX(datte) FROM table1 WHERE contry = 'de') as timingde,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) AND contry = 'it') as yooit,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY AND contry = 'it') as yooyestit,
(select sum(tot) FROM table1 WHERE yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014 AND contry = 'it') as yooyesttit,
(select sum(tot) FROM table1 WHERE MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014 AND contry = 'it') as yooyestttit,
(select MAX(datte) FROM table1 WHERE contry = 'it') as timingit,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) AND contry = 'es') as yooes,
(select sum(tot) FROM table1 WHERE DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY AND contry = 'es') as yooyestes,
(select sum(tot) FROM table1 WHERE yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014 AND contry = 'es') as yooyesttes,
(select sum(tot) FROM table1 WHERE MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014 AND contry = 'es') as yooyestttes,
(select MAX(datte) FROM table1 WHERE contry = 'es') as timinges,
спасибо, Марко.
Комментарии:
1. Было бы полезно включить объяснение того, что именно вы пытаетесь сделать в коде.
2. Возможно, вы захотите проверить
UNION
, но, честно говоря, если вам это нужно для реального кода, вы серьезно можете пересмотреть свой дизайн.
Ответ №1:
Возврат одной строки на округ может быть немного более эффективным:-
SELECT origin_country,
SUM(IF(DATE(datte) = DATE(NOW()), tot, 0)) AS yoofr,
SUM(IF(DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY, tot, 0)) AS yooyestfr,
SUM(IF(yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014, 0)) AS yooyesttfr,
SUM(IF(MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014, 0)) AS yooyestttfr,
MAX(datte) AS timingfr
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
GROUP BY origin_country
Но это все равно не будет здорово (индексы не будут так сильно использоваться в полях суммы)
Возможно, это позволит использовать индексы (если они есть полезные):-
SELECT sub1.origin_country, yoofr, yooyestfr, yooyesttfr, yooyestttfr, timingfr
FROM
(
SELECT origin_country, sum(tot) as yoofr,
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
AND DATE(datte) = DATE(NOW())
GROUP BY origin_country
) sub1
INNER JOIN
(
SELECT origin_country, sum(tot) as yooyestfr
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
AND DATE(datte) = DATE(NOW()) - INTERVAL 1 DAY
GROUP BY origin_country
) sub2 ON sub1.origin_country = sub2.origin_country
INNER JOIN
(
SELECT origin_country, sum(tot) as yooyesttfr
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
AND yearweek(`datte`, 1) = yearweek(curdate(), 1) AND YEAR(datte)=2014
GROUP BY origin_country
) sub3 ON sub1.origin_country = sub3.origin_country
INNER JOIN
(
SELECT origin_country, sum(tot) as yooyestttfr
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
AND MONTH(datte) = MONTH(CURDATE()) AND YEAR(datte)=2014
GROUP BY origin_country
) sub4 ON sub1.origin_country = sub4.origin_country
INNER JOIN
(
SELECT origin_country, MAX(datte) as timingfr
FROM table1
WHERE origin_country IN ('fr', 'de', 'it', 'es')
GROUP BY origin_country
) sub5 ON sub1.origin_country = sub5.origin_country
Однако многое из этого будет зависеть от индексов в ваших реальных таблицах
Комментарии:
1. круто, у меня на самом деле нет индексов в моей таблице. Я предполагаю, что я мог бы создать его, используя поля, присутствующие в моей группе по и где условие, верно?
2. ДА. Индексы, вероятно, будут иметь огромное значение для времени, которое требуется для выполнения запросов.