我有一个看似简单的查询案例,其中添加约束会导致性能下降。使用AND子句约束的三列都是bigint。如果我使用它们中的任何两个(但不是全部三个),查询立即运行,但是一旦我添加第三个AND,它就会运行缓慢。
WITH tb AS (SELECT
DISTINCT u.*
FROM
[user] u
INNER JOIN
user_personal up
ON up.user_id = u.user_id
WHERE
1=1
AND u.site_instance_id = 1
AND u.graduation_class_id = 27
AND u.graduation_term_id IN (76,75)
) SELECT
COUNT (*) AS count
FROM
( SELECT
ROW_NUMBER() OVER (
ORDER BY
last_name ASC) AS row,
*
FROM
tb) sub
这是否与所有这三列都是bigint的事实有关?或者它与那些列上的表索引有关? (我没有为这些列设置任何索引)。或者它可能是别的吗?
注意 - 在这种情况下,AND u.site_instance_id = 1是多余的,但它应该无关紧要,是吗?
编辑使用SET showplan_all ON:
|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1008],0)))
|--Stream Aggregate(DEFINE:([Expr1008]=Count(*)))
|--Nested Loops(Left Semi Join, WHERE:(.[dbo].[user].[user_id] as [u].[user_id]=.[dbo].[user_personal].[user_id] as [up].[user_id]))
|--Clustered Index Scan(OBJECT:(.[dbo].[user].[PK__user__B9BE370F7F60ED59] AS [u]), WHERE:(.[dbo].[user].[site_instance_id] as [u].[site_instance_id]=(1) AND .[dbo].[user].[graduation_class_id] as [u].[graduation_class_id]=(27) AND (.[dbo].[user].[graduation_term_id] as [u].[graduation_term_id]=(75) OR .[dbo].[user].[graduation_term_id] as [u].[graduation_term_id]=(76))))
|--Clustered Index Scan(OBJECT:(.[dbo].[user_personal].[PK__user_per__C701FAD641EDCAC5] AS [up]))
......只有两个AND条款...
|--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1008],0)))
|--Stream Aggregate(DEFINE:([Expr1008]=Count(*)))
|--Hash Match(Left Semi Join, HASH:([u].[user_id])=([up].[user_id]), RESIDUAL:(.[dbo].[user].[user_id] as [u].[user_id]=.[dbo].[user_personal].[user_id] as [up].[user_id]))
|--Clustered Index Scan(OBJECT:(.[dbo].[user].[PK__user__B9BE370F7F60ED59] AS [u]), WHERE:(.[dbo].[user].[graduation_class_id] as [u].[graduation_class_id]=(27) AND (.[dbo].[user].[graduation_term_id] as [u].[graduation_term_id]=(75) OR .[dbo].[user].[graduation_term_id] as [u].[graduation_term_id]=(76))))
|--Clustered Index Scan(OBJECT:(.[dbo].[user_personal].[PK__user_per__C701FAD641EDCAC5] AS [up]))
答案 0 :(得分:2)
我仍然不确定我理解你的问题 - @Hogan有一个更简单的查询版本。尽管如此,您应该在您加入的每个字段以及您一直搜索的任何字段上都有索引。
在您的情况下,我会确保您拥有以下索引:
您也可以考虑单独为WHERE标准中的3个字段中的每个字段添加索引,但这应该会产生更好的性能。另外,请改用@ Hogan的查询。
祝你好运。答案 1 :(得分:1)
故事必须有更多内容。显然,以下内容与发布的代码相同且更简单(我希望更快):
SELECT COUNT(DISTINCT u.user_id)) as count
FROM [user] u
INNER JOIN user_personal up ON up.user_id = u.user_id
WHERE
u.site_instance_id = 1 AND
u.graduation_class_id = 27 AND
u.graduation_term_id IN (76,75)