【问题标题】:sp_executesql with N arguments is causing slow performance带有 N 个参数的 sp_executesql 导致性能下降
【发布时间】:2012-01-25 00:10:24
【问题描述】:

我遇到了使用 activerecord_sqlserver_adapter 的 Rails activerecord 对象的性能问题。这是生成的 sql 的样子,运行速度很慢;

EXEC sp_executesql N'SELECT COUNT(*) FROM [constituents] WHERE [constituents].[constituent_id] IN (N''10016125'', N''483663'', N''530657'', N''535217'')'

以下运行速度非常快;

EXEC sp_executesql N'SELECT COUNT(*) FROM [constituents] WHERE [constituents].[constituent_id] IN (''10016125'', ''483663'', ''530657'', ''535217'')'

适配器将 N 放在 where 子句中的每个项目前面,这会减慢速度。执行计划建议我添加一个索引,但这似乎没有必要,而且这是一个遗留数据库。

有没有人建议我如何加快速度?

【问题讨论】:

  • 您已经提出了 7 个问题但没有接受任何问题?
  • 我回答了类似的问题here

标签: ruby-on-rails sql-server


【解决方案1】:

我强烈推荐阅读How Data Access Code Affects Database PerformanceSlow in the Application, Fast in SSMS? Understanding Performance Mysteries。这两篇文章都非常详细地介绍了这个主题,甚至更多。

总结是Data Type Precedence 的规则规定,涉及VARCHARNVARCHAR 操作数的操作必须通过将 VARCHAR(优先级 27)转换为 NVARCHAR(优先级 25)。因此你的查询真的很像 我在使用 activerecord_sqlserver_adapter 的 Rails activerecord 对象时遇到性能问题。这是生成的 sql 的样子,运行速度很慢;

SELECT COUNT(*) 
FROM [constituents] 
WHERE CAST([constituents].[constituent_id] as NVARCHAR(...))
IN (N''10016125'', N''483663'', N''530657'', N''535217'');

这是不可分割的,这意味着constituent_id 上的索引将被忽略,而是执行表扫描。

但这里真正的问题是,您为什么要使用字符串来进行类似int 的行走和嘎嘎声?不应该是组成_id列int,连同传入的参数?

【讨论】:

  • compart_id 的数据类型是在遗留系统中设置的,所以它就是这样。在这种情况下,我似乎受制于适配器。我认为它将 Ns 放在 sql 中以帮助执行计划缓存,但在这种情况下它伤害了我。感谢您的帮助!
【解决方案2】:

construction_id 是字符串还是数字?如果是字符串,有没有办法告诉你的适配器是varchar还是nvarchar?可能会杀死你的是由此产生的隐式转换。

您是否考虑过先将值插入到表中,然后再执行连接?这可以通过传入逗号分隔的字符串,然后使用 UDF 或 XML 将列表“拆分”为具有匹配数据类型的表来轻松完成。可能看到SQL query to match keywords?

【讨论】:

    【解决方案3】:

    “N”表示 Unicode 字符串。我猜 SQL Server 中的类型不是 Unicode(即 VARCHAR 而不是 NVARCHAR),因此此代码正在生成隐式转换。查看执行计划,看看是否可以在运算符中看到 convert_implicit。如果是这种情况,您需要弄清楚为什么代码生成器假设变量是 Unicode。可能有一些方法可以将变量声明为不转换为 Unicode 的不同类型。

    【讨论】:

      【解决方案4】:

      select counts 进行全表扫描,in 子句也很慢,由于 select count,查询将进行全表扫描。

      将查询分解成小的一行查询。存储计数或使用分区以获得更好的性能。

      索引,会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多