Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何存储查询执行计划以便以后使用_Sql Server_Sql Execution Plan_Sqlperformance - Fatal编程技术网

Sql server 如何存储查询执行计划以便以后使用

Sql server 如何存储查询执行计划以便以后使用,sql-server,sql-execution-plan,sqlperformance,Sql Server,Sql Execution Plan,Sqlperformance,我的应用程序对sql server数据库运行查询 在许多情况下,我可以看到执行计划的好处:例如,我第一次单击按钮 SELECT * from Tasks WHERE IdUser = 24 AND DATE < '12/12/2010' and DATE > '01/01/2010' 从任务中选择* 其中IdUser=24和 日期'01/01/2010' 第一次需要15秒,接下来需要8秒 编辑:我使用参数化查询。 第二次我有7秒的进步 现在,当我再次运行应用程序时(因此我建立

我的应用程序对sql server数据库运行查询

在许多情况下,我可以看到执行计划的好处:例如,我第一次单击按钮

SELECT * from Tasks
WHERE IdUser = 24 AND
  DATE < '12/12/2010' and DATE > '01/01/2010'
从任务中选择*
其中IdUser=24和
日期<'12/12/2010'和日期>'01/01/2010'
第一次需要15秒,接下来需要8秒

编辑:我使用参数化查询。

第二次我有7秒的进步

现在,当我再次运行应用程序时(因此我建立了一个新的数据库连接),第一次需要15秒,第二次需要7秒

如何让SQL Server存储执行计划,至少在同一天记住它们?或者,如何从已经计算的执行计划中获益?如果不同的用户运行相同的查询,这是一种告诉sql server足够聪明以使用相同的执行计划的方法,即使在这种情况下,IdUser可能会不同


在软件中,我有一些参数,因此下一次执行查询时可能会有不同的MinDate和MaxDate,但这会影响查询计划吗?

使用参数化查询以最大限度地提高计划被缓存的可能性

SELECT * from MYTasks 
WHERE IdUser = @UserId AND DATE < @enddate and DATE > @startdate

SQL Server将为您做到这一点—只要有可用空间,任何执行计划都将被存储

但是,您可以做很多事情来增加执行计划被存储和重用的机会。您需要注意的是创建<强>相同的<强> SQL查询-任何到一个额外空间的任何东西都会导致SQLServer认为两个查询不同,不重用现有的查询计划。 因此:

  • 在您的查询中保持一致-始终以相同的方式拼写内容(注意大写/非大写、空格、
    dbo.
    前缀等)

  • 使用参数而不是文字值;如果使用文字值,则不会重用查询计划,并且它们会不必要地填充计划缓存

  • 尽量避免
    SELECT*
    -这意味着查询优化器的选项较少-因为您需要所有列,它通常必须对聚集索引进行扫描。如果您指定了真正需要的三、五、六列,则可能有一个索引覆盖了查询(包含您感兴趣的所有列),因此,查询分析可以使用该索引并对其进行索引扫描/索引查找(并重用该计划)

因此,现在使用以下方法代替SQL:

SELECT (list of fields)
FROM dbo.MYTasks 
WHERE DATE < @EndDate and DATE > @StartDate
SELECT(字段列表)
从dbo.MYTasks
其中日期<@EndDate和DATE>@StartDate

这将显著增加查询计划的重用。

您运行过SQL Server Profiler吗?如果是,您确定编译语句和生成执行计划会花费额外的时间吗

根据您的问题描述,额外的7秒钟可能是建立到数据库的初始连接的时间。也许你已经排除了这个可能性。我不知道


另一个问题是数据缓存。第一次访问数据时,SQL Server会将其加载到缓存中。这可以减少后续查询的时间(假设它可以保存所有数据)。

我使用参数化查询,我从Delphi应用程序运行它们,通过OLEDB将参数化查询传递给服务器。@用户-在我的答案中运行查询时,您得到了什么?好的,我喜欢这样,但我注意到只有在相同的程序执行中才有改进。我试图实现的是在应用程序的两个不同执行中使用执行计划。或者执行计划是否链接到特定会话?@user-否。只要
SET
选项相同,计划就应该共享。@Martin Smith-对不起,SET options是什么意思?@user-类似
SET ARITHABORT ON
的内容请参见表3以获取完整列表否我始终处于连接状态。按下按钮刷新网格并运行查询,但不执行连接。不管怎样,当我衡量这一点时,我正在创建一些虚拟索引,以强制重新创建查询计划。
SELECT (list of fields)
FROM dbo.MYTasks 
WHERE DATE < @EndDate and DATE > @StartDate