如何通过许多可选的过滤参数来提高 SP 的性能?

Vla*_*sky 1 stored-procedures dynamic-sql sql-server-2012

我需要编写许多具有许多可选过滤参数的 SP。在阅读了 Turgay Sahtiyan(Microsoft 的高级 SQL Server 高级现场工程师)的博客后,他提到了完全相同的问题,解决它的方法是通过动态 SQL。在他的幻灯片中找到它http://blogs.msdn.com/b/turgays/archive/2013/09/07/sqlsaturday-243-cape-town-top-10-performance-tips-for-sql-server-developers .aspx

所以我的问题是这是唯一和最好的方法还是有其他选择?

WHERE (@EmployeeFirstName IS NULL OR emp.First_Name LIKE @EmployeeFirstName )
AND (@EmployeeLastName IS NULL OR emp.Last_Name LIKE @EmployeeLastName )
AND (@EmployeeNetworkLogOn IS NULL OR emp.Network_ID LIKE @EmployeeNetworkLogOn )
AND (@EmployeeStatus IS NULL OR emp.Employee_Status = @EmployeeStatus )
AND (@EmployeeType IS NULL OR emp.Employee_Type = @EmployeeType )
AND (@SupervisorFirstName IS NULL OR sup.First_Name LIKE @SupervisorFirstName )
AND (@SupervisorLastName IS NULL OR sup.Last_Name LIKE @SupervisorLastName )
AND (@SupervisorNetworkLogOn IS NULL OR sup.Network_ID LIKE @SupervisorNetworkLogOn) 
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 7

很难就“最佳”的含义达成共识,因为动态 SQL 需要权衡(根据参数,您可以为每个查询版本获得一些计划稳定性,但会失去可读性、智能感知等功能) , 等等)。我在许多实现中使用了动态 SQL 路由,我强烈推荐它。

由于您将向服务器发送许多不同的查询,因此最好与Optimize for Ad Hoc Workloads服务器设置结合使用。这可以防止任何计划被完全缓存并占用宝贵的内存,直到两次提交相同的查询文本。如果您看到由于参数嗅探而导致性能大幅下降,您可以考虑OPTION (RECOMPILE)在所有情况下都添加到查询中(或者至少在最终导致计划偏差很大的情况下)。例如,当参数是 PK 并且查询最终是使用搜索的完全匹配时,您可能不会看到任何倾斜。但是,当使用日期时间范围时,您可能会看到更大的倾斜,或者与具有自己的不对称倾斜的列完全匹配,特别是当统计数据没有严格维护时(或没有索引支持这些特定查询)。

  • @SaUce 这就像问丰田皮卡 vs. Cannondale 山地自行车。它们用于解决不同的问题,通常,CLR 不太擅长数据访问。您可能想用它来帮助构建您的 SQL 字符串,但我认为您不会从抽象逻辑的那部分中获得很多好处。 (3认同)