[英]SQL CASE WHEN <Value> IN Slow on SQL Server 2005 but not 2000
I have a very simple query that is driving me absolutely nuts. 我有一个非常简单的查询,这使我感到非常疯狂。
Here's the situation: 情况如下:
I've tried creating different indexes on the SQL Server 2005 tables, defragged all the indexes that exist, updated table statistics, etc. Nothing has been able to make this query run faster on SQL Server 2005. Currently nothing else is running against the SQL Server 2005 server, and our DBAs assure me it's not a configuration issue or anything to do with feature deprecation between SQL Server 2000 and SQL Server 2005. 我试过在SQL Server 2005表上创建不同的索引,对所有存在的索引进行碎片整理,更新表统计信息等。没有任何方法能够使此查询在SQL Server 2005上更快地运行。目前,没有其他针对SQL的运行Server 2005服务器以及我们的DBA向我保证,这不是配置问题,也不是与SQL Server 2000和SQL Server 2005之间的功能弃用无关。
The query is below: 查询如下:
SELECT (CASE
WHEN TeamMember.ID IN (SELECT DISTINCT ProjMgrID FROM ProjMgr)
THEN 'Yes'
ELSE 'No'
END) AS OnProjAsMgr
FROM TeamMember
So return a distinct list of all the ProjMgrs, and if the TeamMember is on that list then assign "Yes" to the OnProjAsMgr value. 因此,返回所有ProjMgr的唯一列表,如果TeamMember在该列表上,则将OnProjAsMgr值分配为“是”。
I'm a total SQL newbie, and this is code written by a predecessor. 我是一个SQL新手,这是前辈编写的代码。 I don't know if there's a better way to write it, but I cannot figure out why it runs great on SQL Server 2000 but completely implodes on SQL Server 2005.
我不知道是否有更好的方法编写它,但是我无法弄清楚为什么它在SQL Server 2000上可以很好地运行,而在SQL Server 2005上却完全崩溃。
DISTINCT causes a sort, and IN causes the entire query to be evaluated. DISTINCT引起排序,而IN引起对整个查询的求值。 How does this version work:
这个版本如何运作:
SELECT OnProjAsMgr = CASE WHEN EXISTS
(SELECT 1 FROM dbo.ProjMgr WHERE ProjMgrID = TeamMember.ID)
THEN 'Yes'
ELSE 'No'
END
FROM dbo.TeamMember;
If that fares no better then I suspect indexes are missing and no query will perform well without them. 如果情况没有改善,那么我怀疑索引会丢失,没有索引,查询将无法正常执行。
I don't know about "better" way, but here's a different way that you can try: 我不知道“更好”的方式,但是您可以尝试以下不同的方式:
SELECT ... other fields you want ...,
CASE WHEN ProjMgr.ProjMgrID IS NULL
THEN 'No'
ELSE 'Yes'
END AS OnProjAsMgr
FROM TeamMember
LEFT
OUTER
JOIN ProjMgr
ON ProjMgr.ProjMgrID = TeamMember.ID
;
Notes: 笔记:
SELECT DISTINCT ProjMgrID FROM ProjMgr
. SELECT DISTINCT ProjMgrID FROM ProjMgr
。 If that is actually different from SELECT ProjMgrID FROM ProjMgr
— that is, if there are actually duplicate values of ProjMgrID
in ProjMgr
— then the above query is not exactly equivalent to yours, since it will give a separate record for each duplicate. SELECT ProjMgrID FROM ProjMgr
实际上不同(也就是说,如果ProjMgrID
中ProjMgr
有ProjMgrID
重复值),则上述查询与您的查询不完全相同,因为它将为每个重复项提供单独的记录。 You might have to add a GROUP BY
clause in that case. GROUP BY
子句。 SELECT DISTINCT ProjMgrID FROM ProjMgr
is equivalent to SELECT ProjMgrID FROM ProjMgr
for your data, as I suspect, then it also might be worth removing the DISTINCT
, since that might affect the optimizer as well. SELECT DISTINCT ProjMgrID FROM ProjMgr
到您的数据等效于SELECT ProjMgrID FROM ProjMgr
,那么删除DISTINCT
也可能是值得的,因为这也会影响优化器。 SELECT (
CASE WHEN P.ID IS NULL THEN 'No' ELSE 'Yes' END
) AS OnProjAsMgr
FROM TeamMember AS T
LEFT OUTER JOIN ProjMgr AS P ON T.ID=P.ID
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.