AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 7515
Accepted
RateControl
RateControl
Asked: 2011-11-03 07:42:23 +0800 CST2011-11-03 07:42:23 +0800 CST 2011-11-03 07:42:23 +0800 CST

查询在 SQL 2005 与 SQL 2008R2 上的运行方式不同

  • 772

在我的办公室,我们有一个非常丑陋的查询,但在生产环境和开发环境中运行良好(分别为 20 秒和 4 秒)。然而,在我们的测试环境中,它需要超过 4 小时。SQL2005(+最新补丁)正在生产和开发中运行。SQL2008R2 正在测试中运行。

我查看了查询计划,它显示 SQL2008R2 正在使用 TempDB,通过表假脱机(惰性假脱机)来存储从链接服务器返回的行。下一步显示嵌套循环(左反半连接)占用了 96.3% 的查询。两个运营商之间的界线是 5,398MB!

SQL 2005 的查询计划显示没有使用 tempdb,也没有使用 Left Anti Semi Join。

下面是经过清理的代码和执行计划,顶部是 2005 计划,底部是 2008R2。

是什么导致了急剧的减速和变化?我期待看到不同的执行计划,所以这不会打扰我。查询时间的急剧下降让我很困扰。

我是否必须查看底层硬件,因为 2008R2 版本使用的是 tempdb 我必须看看如何优化它的使用?

有没有更好的方法来编写查询?

谢谢您的帮助。

    INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT 
 Table1.iGroupID,
 GETDATE()
FROM Table1
WHERE 
 NOT EXISTS (
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE 
   (
    Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
    AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
    AND NOT Alias2.FirstName IS NULL 
    AND NOT Alias2.LastName  IS NULL
   ) OR (
    Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
    AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
    AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
    AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
    AND NOT Alias2.Familyname IS NULL
    AND NOT Alias2.Child1Name IS NULL
   ) OR (
    Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
    AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
    AND NOT Alias2.StepFamilyName IS NULL
    AND NOT Alias2.StepFamilyNameChild1 IS NULL
    AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
    AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
   )  
 ) AND NOT EXISTS (
  SELECT 1
  FROM Table3
  INNER JOIN Table4
   ON Table4.FirstNameType = Table3.FirstNameType 
  INNER JOIN table5
   ON table5.LastNameType = Table3.LastNameType 
  WHERE 
   Table3.iGroupID = Table1.iGroupID
   AND Table3.bIsClosed = 0
   AND Table4.sNameTypeConstant = 'new_lastname'
   AND table5.sFirstNameConstant = 'new_firstname'
 )

SQL-2005


SQL2008R2

:: 编辑 :: 从不同的 SQL2005 实例执行查询,与“好”的执行计划几乎相同。仍然不确定两个 2005 版本对 2008R2 链接服务器的运行效果如何优于 2008R2 实例对 2008R2 实例的运行效果。

虽然我不否认代码可以使用一些工作,但如果代码是问题所在,我不会在我的所有试验中看到相同的执行计划吗?不管SQL版本如何?

:: 编辑 :: 我已将 SP1 和 CU3 应用于两个 2008R2 实例,但仍然没有骰子。我在链接服务器中专门设置了搭配,没有骰子。我已将我的用户帐户的权限专门设置为两个实例上的系统管理员,没有骰子。我还记得我的 sql server 2008 内部结构和故障排除,我们将看看我是否能找到一些方法。

感谢大家的帮助和提示。

:: 编辑 :: 我对链接服务器进行了各种权限更改。我使用过 SQL 登录、域登录、模拟用户、使用过“使用此安全上下文”选项。我在链接服务器的两端都创建了在服务器上具有系统管理员权限的用户。我没主意了。

我仍然想知道为什么 SQL2005 执行的查询与 SQL2008R2 截然不同。如果是查询不好,我会在 SQL2005 和 SQL2008R2 上看到 4 小时以上的运行时间。

sql-server-2008 sql-server-2005
  • 5 5 个回答
  • 4090 Views

5 个回答

  • Voted
  1. Paul White
    2011-11-03T21:44:11+08:002011-11-03T21:44:11+08:00

    添加到前面的答案中,计划回归的原因可能是由于计划包含反半联接时已知的基数估计错误。见知识库 2222998

    假设 2005 计划产生了可接受的性能,您可能会发现将服务器升级到包含该修复程序的版本(并启用 TF4199 来激活它)将使您返回“良好”计划。

    也就是说,还有许多其他机会可以改进该查询,因此这可能是专注于这样做的好时机。

    • 6
  2. gbn
    2011-11-03T07:55:24+08:002011-11-03T07:55:24+08:00

    我建议远程数据在本地假脱机,因为其中之一

    1. Linked Server 设置(如排序规则)不相同
    2. 尽管有链接服务器设置,但本地排序规则与远程排序规则不同
    3. 由于权限问题,查询无法远程正确运行

    对于第 1 点,请参阅sp_serveroption
    对于第 2 点,还要检查 server/db 排序规则。

    对于第 3 点,请参阅 Linchi Shea 的这些:

    • 链接服务器:权限和分布式查询性能
    • 性能影响:链接服务器安全配置及其对您的伤害

    您要求 SQL Server 在本地处理所有数据,按照我的回答: 在视图中使用 OPENQUERY 的性能影响

    编辑

    再看一遍,我看到“好”计划有 2 个远程调用,而不是 1 个。这证实了我在这里所说的

    • 5
  3. Best Answer
    Rob Farley
    2011-11-03T22:06:38+08:002011-11-03T22:06:38+08:00

    我希望您重新编写查询。

    您有 sargability 问题,甚至在那里使用标量函数调用,这也会损害查询。您可能希望在 Table2 上创建一个 FullName 计算列并在其上放置一个索引,确保您的索引包括 FirstName 和 LastName。您还应该添加有助于其他人的索引

    此外,制作一个内联表值函数来执行“RemoveNonLetter”功能,并重新编写查询以使用它,可能像我在这里所做的那样使用 APPLY。

    并且一定要检查保罗的回答 所指的那个错误。

    INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
    SELECT 
     Table1.iGroupID,
     GETDATE()
    FROM Table1
    OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FullName)) AS fn (FullName)
    OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FamilyName)) AS famn (FamilyName)
    OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.Child1Name)) AS c1n (Child1Name)
    OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyName)) AS sfn (StepFamilyName)
    OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyNameChild2)) AS sfnc2 (StepFamilyNameChild2)
    WHERE 
     NOT EXISTS (
      SELECT 1
      FROM LinkedServer.Database.Table2 Alias2
      WHERE Alias2.FullName = fn.FullName
      UNION ALL
      SELECT 1
      FROM LinkedServer.Database.Table2 Alias2
      WHERE Alias2.FamilyName = famn.FamilyName AND Alias2.Child1Name = c1n.Child1Name
      UNION ALL
      SELECT 1
      FROM LinkedServer.Database.Table2 Alias2
      WHERE Alias2.StepFamilyName = sfn.StepFamilyName AND Alias2.StepFamilyNameChild1 = sfnc2.StepFamilyNameChild2
     ) 
     AND NOT EXISTS (
      SELECT 1
      FROM Table3
      INNER JOIN Table4
       ON Table4.FirstNameType = Table3.FirstNameType 
      INNER JOIN table5
       ON table5.LastNameType = Table3.LastNameType 
      WHERE 
       Table3.iGroupID = Table1.iGroupID
       AND Table3.bIsClosed = 0
       AND Table4.sNameTypeConstant = 'new_lastname'
       AND table5.sFirstNameConstant = 'new_firstname'
     )
    ;
    
    • 5
  4. datagod
    2011-11-03T07:49:24+08:002011-11-03T07:49:24+08:00

    这种比较有很多问题......我只是不知道从哪里开始。

    1. 为您的生产和测试机器获取准确的规格。

    2. 确定两种环境中各种链接服务器之间的网络链接。他们的速度一样吗?两种环境中的服务器是否彼此相邻?

    3. 有什么办法可以重写查询以不使用链接服务器?跨服务器连接表会使您容易受到拓扑变化的影响,并且在大多数情况下他的速度非常慢。

    4. 使用 NOT 和 OR 通常会导致全表扫描。尝试重写查询。

    • 3
  5. Mike Walsh
    2011-11-03T07:53:36+08:002011-11-03T07:53:36+08:00

    +1 尝试从 datagod 重写您的查询评论。

    我还想知道您是否在链接服务器端遇到权限问题,从而导致速度变慢。不久前,我在博客中谈到了这个链接服务器的减速。可能值得验证 perms(它是 SQL 链接服务器吗?还是另一个 DBMS?如果是后者,那么无论如何你都不会得到很好的统计数据)

    您是否还在测试环境中使用 SQL Server 2005 来尝试此查询并排除该环境?

    升级后您是否重建了统计信息?

    • 3

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve