简体   繁体   English

SQL情况 <Value> 在SQL Server 2005而不是2000上运行缓慢

[英]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 have two database servers. 我有两个数据库服务器。
  • One is an old SQL Server 2000 (VM), very minimal resources. 一种是旧的SQL Server 2000(VM),资源非常少。
  • The other is a very large SQL Server 2005 enterprise cluster with an absolutely ridiculous amount of resources available. 另一个是非常大的SQL Server 2005企业群集,具有绝对可笑的可用资源量。
  • I have a small portion of a larger query that executes in 3 seconds and returns 50,000+ rows of data on SQL Server 2000 我在3秒钟内执行较大查询的一小部分,并在SQL Server 2000上返回50,000多行数据
  • This same small query takes upwards of 15 minutes to return 1000 rows on SQL Server 2005 此相同的小查询需要15分钟以上的时间才能在SQL Server 2005上返回1000行
  • The database I'm working with is a mirror image on these two servers. 我正在使用的数据库是这两个服务器上的镜像。 Same tables, same data in tables, same indexes on tables, etc. 相同的表格,表格中的相同数据,表格上的相同索引等。

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: 笔记:

  • On some DBMSes, this will perform much better than your query, but I don't know whether it would perform better on SQL Server 2005, given that your query already works fine on SQL Server 2000. I think you'll just have to try it. 在某些DBMS上,这将比您的查询更好地执行,但是我不知道它在SQL Server 2005上是否会更好地执行,因为您的查询在SQL Server 2000上已经可以正常工作。我想您只需尝试一下它。
  • Your query uses 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实际上不同(也就是说,如果ProjMgrIDProjMgrProjMgrID重复值),则上述查询与您的查询不完全相同,因为它将为每个重复项提供单独的记录。 You might have to add a GROUP BY clause in that case. 在这种情况下,您可能必须添加GROUP BY子句。
  • For that matter, if 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM