我希望这个问题的答案不是“依赖”。
我必须编写一份报告,它是类数据的摘要。每个班级都包含汇总的学生数据,如成绩,出勤率等。其中一些数据,如成绩,是所有评分作业的汇总数据。
查询有效,但我发现我写了一个不可维护的怪物,大约15张桌子连在一起。如果我使用派生表重写了查询,我会帮助或损害性能吗?
答案 0 :(得分:0)
就性能而言,您可以通过添加索引来获得改进。加入将非常快。
对于可维护性(和可读性),派生表可能有所帮助。此外,您可以创建视图以分离逻辑。
此外,您可以考虑使用汇总数据创建表,然后运行简单的select * from summary
答案 1 :(得分: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
;
在派生表之前聚合,然后加入。费用.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
;