我有一个查询在4秒内运行,但在WHERE中没有is null
,但在is null
需要几分钟时间。我已经阅读了空检查对性能的影响,但在这种情况下,我无法修改正在运行的查询。我可以修改索引或视图以提高'空'子句的性能
select
view_scores.*
from
view_scores
inner join licenses AS l on view_scores.studentId = l.account_id
where view_scores.archived_date is null
and l.school_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
and l.is_current = 1
and l.expiration_date >= SYSDATETIME()
view_scores是一个视图,它汇集其他表中的数据的其他视图,其中一个视图最终保存archived_date字段。该字段中的空值意味着它尚未归档。同样,数据结构不在我的控制范围之内。我现在可以改变的是所涉及的观点的内部和表格上的索引。我是否有希望在不更改查询或模式的情况下显着提高对archived_date的空检查?
view_scores
与此SQL
SELECT
ueh.user_id AS studentId,
vu.first_name + ' ' + vu.last_name AS studentName,
ueh.archived_date as archived_date,
MIN([ueh].[date_taken]) AS [started_date],
MAX(ueh.date_taken) AS last_date,
SUM(CAST([ueh].[actual_time] AS FLOAT)/600000000) AS [total_time_minutes],
SUM([exercise_scores].[earned_score]) AS [earned_score],
SUM([exercise_scores].[possible_score]) AS [possible_score],
AVG([exercise_scores].[percent_score]) AS [percent_score],
COUNT(ueh.exercise_id) AS total_exercises
FROM [user_exercise_history] AS [ueh]
LEFT JOIN
(
SELECT
coding_exercise_score.exercise_id AS exercise_id,
coding_exercise_score.assessment_id AS assessment_id,
coding_exercise_score.user_id AS user_id,
coding_exercise_score.archived_date AS archived_date,
score.earned AS earned_score,
score.possible AS possible_score,
CASE score.possible
WHEN 0 THEN 0
WHEN score.earned THEN 100
ELSE 9.5 * POWER(CAST(score.earned AS DECIMAL)/score.possible * 100, 0.511)
END AS percent_score
FROM coding_exercise_score
INNER JOIN
coding_exercise_score_detail AS score_detail
ON coding_exercise_score.id = score_detail.exercise_score_id
INNER JOIN
score
ON score.id = score_detail.score_id
WHERE score_detail.is_best_score = 'True'
UNION
SELECT
mc_score.exercise_id AS exercise_id,
mc_score.assessment_id AS assessment_id,
mc_score.user_id AS user_id,
mc_score.archived_date AS archived_date,
score.earned AS earned_score,
score.possible AS possible_score,
CASE score.possible
WHEN 0 THEN 0
WHEN score.earned THEN 100
ELSE 9.5 * POWER(CAST(score.earned AS DECIMAL)/score.possible * 100, 0.511)
END AS percent_score
FROM
multiple_choice_exercise_score AS mc_score
INNER JOIN score
ON score.id = mc_score.score_id
) AS [exercise_scores]
ON
(
(ueh.exercise_id = [exercise_scores].exercise_id
AND ueh.user_id = [exercise_scores].user_id
AND (
(ueh.assessment_id IS NULL AND [exercise_scores].assessment_id IS NULL)
OR ueh.assessment_id = [exercise_scores].assessment_id
)
AND (ueh.archived_date IS NULL)
)
)
INNER JOIN entity_account AS vu ON ((ueh.user_id = vu.account_id))
INNER JOIN (
select
g.group_id,
g.entity_name,
g.entity_description,
g.created_on_date,
g.modified_date,
g.created_by,
g.modified_by,
agj.account_id
from entity_group as g
inner join
account_group_join as agj
on agj.group_id = g.group_id
where g.entity_name <> 'Administrators'
and g.entity_name <> 'Group 1'
and g.entity_name <> 'Group 2'
and g.entity_name <> 'Group 3'
and g.entity_name <> 'Group 4'
and g.entity_name <> 'Group 5'
) AS g ON ueh.user_id = g.account_id
WHERE ueh.status = 'Completed'
GROUP BY ueh.user_id, vu.first_name, vu.last_name, ueh.archived_date
user_exercise_history.archived_date AS archived_date
是外地的空支票最终被执行针对创建。我可以以任何我想要的方式修改视图并以任何我想要的方式编制索引,但这就是它。
带有空检查的执行计划包含一组非常疯狂的排序和散列匹配,它们与score和coding_exercise_score_detail有关。
'EXEC sp_updatestats;'到你的数据库更新统计。任何改变? – Mihai
所以如果你可以改变视图的内部,我们可以看到创建视图的sql吗? – HLGEM
你是否在视图中调用任何其他视图?如果是这样,这通常是一个坏主意。我们几乎失去了一个数百万美元的客户,因为一个不知情的人对围绕着视图的观点进行了整体设计。 – HLGEM