0

我希望这个问题的答案不是“取决于”。

我必须写一份报告,这是对班级数据的总结。每个班级都包含汇总的学生数据,例如成绩、出勤率等。其中一些数据(例如成绩)是所有已评分作业的汇总数据。

查询有效,但我意识到我已经编写了一个无法维护的怪物,将大约 15 个表连接在一起。如果我使用派生表重写查询,我会帮助还是损害性能?

4

2 回答 2

0

实际上最终成为使用派生表的性能提升。我意识到我有一个相当糟糕的问题。给个小片段吧……

在 JOIN 之后聚合。成本 .937

DECLARE @0 INT = 141;

SELECT u.id, u.first_name, u.last_name, 
    CAST(CAST(COUNT(haid.mastered_date) AS DECIMAL) / CAST(COUNT(sa.id) AS DECIMAL) * 100 AS DECIMAL(4, 1)) AS mastery_perc
FROM reporting_saved_reports r
JOIN reporting_saved_reports_sections sr ON sr.report_id = r.id
JOIN ums_ae_instructor_section_order_user isou ON isou.instructor_section_id = sr.section_id
JOIN ums_users u ON u.id = isou.user_id
JOIN reporting_states sa ON sa.tutor_id = r.Tutor_Id
    AND sa.business_type IN ('B', r.business_type)
    AND sa.haid = 'Y'
LEFT JOIN reporting_wrapup_haid haid ON haid.tutor_id = r.Tutor_Id
    AND haid.section_id = isou.instructor_section_id
    AND haid.user_id = isou.user_id
    AND haid.state_id = sa.id
    AND haid.mastered_date BETWEEN r.from_date AND r.to_date
WHERE r.id = @0
GROUP BY u.id, u.first_name, u.last_name
ORDER BY u.last_name, u.first_name
;

先与派生表聚合,然后加入。成本 0.546

DECLARE @0 INT = 141;

WITH wr AS (
    SELECT r.id AS report_id, r.Tutor_Id, r.from_date, r.to_date, r.business_type, sr.section_id, isou.user_id
    FROM reporting_saved_reports r
    JOIN reporting_saved_reports_sections sr ON sr.report_id = r.id
    JOIN ums_ae_instructor_section_order_user isou ON isou.instructor_section_id = sr.section_id
    WHERE r.id = @0
)
SELECT dual.user_id, dual.first_name, dual.last_name,
    CAST(CAST(haid.mastered_count AS DECIMAL) / CAST(dual.state_count AS DECIMAL) * 100 AS DECIMAL(4, 1)) AS mastery_perc
FROM (
    SELECT wr.user_id, u.first_name, u.last_name, COUNT(sa.id) AS state_count
    FROM ums_users u
    JOIN wr ON wr.user_id = u.id
    JOIN reporting_states sa ON sa.tutor_id = wr.Tutor_Id
        AND sa.business_type IN ('B', wr.business_type)
        AND sa.haid = 'Y'
    GROUP BY wr.user_id, u.first_name, u.last_name
) dual
LEFT JOIN (
    SELECT haid.user_id, COUNT(haid.mastered_date) AS mastered_count
    FROM reporting_wrapup_haid haid
    JOIN wr ON wr.Tutor_Id = haid.tutor_id
        AND wr.section_id = haid.section_id
        AND wr.user_id = haid.user_id
        AND haid.mastered_date <= wr.to_date
    GROUP BY haid.user_id
) haid ON haid.user_id = dual.user_id
ORDER BY dual.last_name, dual.first_name
;
于 2012-12-17T15:42:34.017 回答
0

性能而言,您可以通过添加索引来获得改进。加入将非常快。

可维护性(和可读性)而言,派生表可能会有所帮助。此外,您可以创建视图以分离逻辑。

此外,您可以考虑使用聚合数据创建表,然后运行一个简单的select * from summary

于 2012-12-17T05:03:30.173 回答