Запрос останавливается, никогда не заканчивается

  • Автор темы Neakrisse
  • 62
  • Обновлено
  • 12, May 2024
  • #1
Так что я предполагаю, что у меня что-то не так, и я просто этого не вижу.

Еще одна пара глаз была бы оценена по достоинству
 SELECT

DISTINCT

Finance.`startdate`

,

(SELECT

COUNT(Fin.id)

FROM

finances AS Fin

, memberships AS Membership

WHERE Fin.membership_id = Membership.id

AND Membership.softdelete = 'N'

AND Membership.association_id = 4

AND Finance.startdate >= Fin.startdate

AND Finance.startdate <= Fin.enddate)

FROM

finances AS Finance

WHERE Finance.`startdate` < NOW()

ORDER BY Finance.startdate DESC

LIMIT 20
Код (разметка): Основной запрос просто обращается к таблице и получает список дат — первого числа каждого месяца. Подзапрос берет этот месяц и пытается выяснить, сколько финансовых записей было «активно» в этом месяце — обычно финансовая запись активна в течение года, но это может отличаться.

Вот почему у вас есть сравнение дат начала и окончания. Все началось с объединений, но эта старая школьная табличная штука тоже должна работать.

Neakrisse


Рег
11 Jun, 2012

Тем
1

Постов
3

Баллов
13
  • 01, Jun 2024
  • #2
финансы довольно большие по нашим меркам, но на самом деле мизерные - 42 тыс. Запрос является разовым и может превратиться в отчет, но будет выполняться нечасто. Я приведу в порядок имена таблиц, обратные галочки и т. д., когда/если это произойдет.
 

inettman


Рег
04 Jul, 2011

Тем
1

Постов
2

Баллов
12
  • 13, Jun 2024
  • #3
Я почти закончил, и он выполняется чуть больше секунды, что довольно хорошо, предыдущие итерации занимали почти 2 минуты.

Там, где у меня были подзапросы при выборе столбца, я переместил их в раздел «От». Все еще использую старое объединение таблиц, но оно выполняет свою работу.
 

SELECT

`Finance`.`startdate`

, COUNT(`F2`.`id`) AS total

, SUM(

CASE

WHEN Finance.startdate = F2.startdate

THEN

CASE

WHEN F2.nrstatus = 0

THEN 1

ELSE 0

END

ELSE 0

END

) AS newmembers

, SUM(

CASE

WHEN Finance.startdate = F2.startdate

THEN

CASE

WHEN F2.nrstatus = 0

THEN 0

ELSE 1

END

ELSE 0

END

) AS renewmembers

FROM

(SELECT DISTINCT

F.startdate

FROM

finances AS F

WHERE F.startdate BETWEEN DATE_ADD(NOW(), INTERVAL - 2 YEAR)

AND NOW()

ORDER BY F.startdate DESC

LIMIT 20) AS Finance

, memberships AS Membership

,

(SELECT

startdate, enddate

, F1.id

, F1.membership_id

,

(SELECT

COUNT(Fcheck.id)

FROM

finances AS Fcheck

WHERE F1.startdate > Fcheck.startdate

AND F1.`membership_id` = Fcheck.`membership_id`) AS nrstatus

FROM

finances AS F1) AS F2

WHERE `F2`.`membership_id` = `Membership`.`id`

AND Membership.softdelete = 'N'

AND Membership.association_id = 4

AND Finance.startdate >= F2.startdate

AND Finance.startdate <= F2.enddate

GROUP BY Finance.startdate

ORDER BY Finance.startdate DESC
Код (разметка):
 

proty


Рег
27 Oct, 2011

Тем
0

Постов
2

Баллов
2
  • 15, Jun 2024
  • #4
Я знаю, что в вашей ситуации это не поможет, но если вы можете избежать подзапросов, сделайте это.

Например, если вы ищете статическое значение с помощью подзапроса, лучше выполнить запрос, который вы делаете с помощью подзапроса, получить значение в своем приложении, а затем статически применить это значение к запросу.

В итоге вы получите 2 запроса вместо 1, но, скажем, у вас есть 100 000 записей в запрашиваемой таблице.

Внутренне MySQL может выполнять 100 000 повторяющихся запросов (по одному для каждой строки), поэтому внутренне MySQL может выполнять 100 001 запрос. Конечно, это зависит от подзапроса, и его не всегда можно избежать, но в любой момент, когда есть возможность их избежать, сделайте это.
 

Scruff


Рег
30 Nov, 2012

Тем
0

Постов
3

Баллов
3
Тем
49554
Комментарии
57426
Опыт
552966

Интересно