sql-server - 条件存储过程性能与代码构建语句
问题描述
目前我正在为我们的数据存档开发一个报告系统。目的是为每个月的第一天、每个整小时等选择数据。所以我有一堆参数可以选择一个小时内的数据。
为了实现这一点,我使用 CASE 语句来调整选择,如下所示:
SELECT
MIN(cd.Timestamp) as Mintime,
--Hours
CASE
WHEN
@SelHour IS NOT NULL
THEN
DATEPART(HOUR, cd.Timestamp)
END as Hour,
... -- more CASES up to DATEPART(YEAR, cd.Timestamp)
FROM dbo.CustomerData cd
... -- filter data and other stuff
到目前为止,这条语句对我很有用,但我有点担心存储过程的性能。因为我不知道服务器将如何处理这个“变化”的语句。结果可以在 20 行结果到 250.000 行或更多行之间变化。取决于给定的参数。据我所知,sql server 会保存查询计划并将其重用于将来的执行。当它保存 20 行结果的计划时,250.000 结果的性能可能很差。
现在我想知道什么是更好的方法。使用这个存储过程还是在我的 c# 后端创建语句并将“调整后的”语句传递给 sql server?
谢谢和问候
解决方案
对于 20 行结果集,它在任何地方都可以正常工作。但是对于将 250k 记录返回到 c# 代码,此代码的设计似乎发生了变化,因为在内存中加载 250k 记录和循环也会消耗大量内存,并且来自不同会话/用户的此类并发请求将成倍增加负载。
无论如何,要解决 SQL Server 重用相同查询计划的问题,您可以有选择地或每次重新编译查询计划。这些是可用于重新编译执行计划的选项:
选项(重新编译)
SELECT MIN(cd.Timestamp) as Mintime, --Hours CASE WHEN @SelHour IS NOT NULL THEN DATEPART(HOUR, cd.Timestamp) END as Hour, ... -- more CASES up to DATEPART(YEAR, cd.Timestamp) FROM dbo.CustomerData cd ... -- filter data and other stuff OPTION(RECOMPILE)
WITH RECOMPILE 选项这将每次重新编译执行计划
CREATE PROCEDURE dbo.uspStoredPrcName @ParamName varchar(30) = 'abc'
WITH RECOMPILE
AS
...RECOMPILE Query Hint
WITH RECOMPILE
在执行中提供
注意:这将需要数据库中的 CREATE PROCEDURE 权限和正在创建过程的模式的 ALTER 权限。
EXECUTE uspStoredPrcName WITH RECOMPILE;
GO
- sp_recompile系统存储过程
注意:需要指定过程的 ALTER 权限。
EXEC sp_recompile N'dbo.uspStoredPrcName ';
GO
有关重新编译的更多详细信息,请参阅 Microsoft Docs: https ://docs.microsoft.com/en-us/sql/relational-databases/stored-procedures/recompile-a-stored-procedure?view=sql-server-ver15
推荐阅读
- scala - 使用Scala列出给定HDFS路径的所有子目录到一定深度?
- git - 我尝试迁移 Azure Devops 中的一个工作项,该工作项具有指向 git 存储库中分支的链接,但该链接没有被迁移
- ios - 使用 Vuforia 8.5.9 构建 Unity iOS 版本 2019.3.0f1 时出现此构建时间错误
- wordpress - 无法使用 XAMPP 在本地安装 wordpress 插件
- c# - ASP.NET Core 3.1 Web API 基于角色的授权不起作用
- webpack - 如何在 monorepo 中配置 Create React App 以使用 root babel.config.js?
- matplotlib - 可视化:通过 matplotlib 和 seaborn 创建的图形的-x-labels 和标题未正确显示
- c - 访问另一个结构内的'typedef struct with char array'
- flutter - Flutter:检查互联网连接并根据输出导航?
- java - 环境中没有应用程序属性