Должен ли я написать длинный SQL запрос или разбить на несколько итераций - PullRequest
0 голосов
/ 10 января 2020

У меня очень длинный запрос SQL для получения ожидаемого вывода, но с другой стороны, я также могу генерировать ожидаемый вывод, используя несколько итераций.

Какой из них использовать? Я забочусь о производительности и пишу лучший код.

  • При использовании запроса длины SQL требуется около 3000 мс для генерации вывода
  • Требуется около 4 ~ 5 итераций для генерации вывода

Что делает запрос / код

Этот код генерирует общее количество записей прогноза на основе финансового года, независимо от того, равно ли общее число 0 или нет.

Использование длины SQL Запрос

SELECT
    CONCAT('FY\'', SUBSTR(`quarters`.fy, 3), ' Q', `quarters`.fy_quarter) AS name,
    (
        SELECT
            COUNT(*) 
        FROM
            member_project_stages 
        WHERE
            YEAR ( member_project_stages.start_at ) = `quarters`.fy 
            AND QUARTER ( member_project_stages.start_at ) = `quarters`.fy_quarter 
            AND member_project_stages.stage_id = 9 
    ) AS actual,
    (
    SELECT
        COUNT(*)
    FROM
        projects AS a 
    WHERE
        ( a.forecast IS NOT NULL AND a.forecast > '' ) 
        AND a.forecast LIKE CONCAT( '%FY\'', SUBSTR( `quarters`.fy, 3 ), '%' ) 
        AND a.forecast LIKE CONCAT( '% Q', `quarters`.fy_quarter, '%' ) 
        AND a.deleted_at IS NULL 
    GROUP BY
        a.forecast 
    ) AS forecast 
FROM
    `member_project_stages`,
    (
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL - 9 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL - 9 MONTH )) AS fy_quarter UNION
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL - 6 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL - 6 MONTH )) AS fy_quarter UNION
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL - 3 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL - 3 MONTH )) AS fy_quarter UNION
    SELECT YEAR
        (
        CURDATE()) AS fy,
        QUARTER (
        CURDATE()) AS fy_quarter UNION
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL 3 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL 3 MONTH )) AS fy_quarter UNION
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL 6 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL 6 MONTH )) AS fy_quarter UNION
    SELECT YEAR
        (
        DATE_ADD( CURDATE(), INTERVAL 9 MONTH )) AS fy,
        QUARTER (
        DATE_ADD( CURDATE(), INTERVAL 9 MONTH )) AS fy_quarter
    ) AS `quarters`
GROUP BY
    `quarters`.fy,
    `quarters`.fy_quarter"

Использование итерации

for(...) {
    run SQL query
}

for(...) {
    using the previous output and run SQL query again
}

for(...) {
    using the previous output and run SQL query again
}

for(...) {
    using the previous output and run SQL query again
}

Finally I have my output

1 Ответ

0 голосов
/ 10 января 2020

Это правда, что взаимодействие с БД обходится дороже. Поэтому люди предпочитают объединять несколько запросов в один запрос для оптимизации производительности. И для лучшего кода, почему бы не объяснить логи c в комментариях.

...