如何存储查询执行计划,以便以后使用它们

时间:2010-09-02 16:02:28

标签: sql-server sql-execution-plan sqlperformance

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

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

SELECT * from Tasks
WHERE IdUser = 24 AND
  DATE < '12/12/2010' and DATE > '01/01/2010'

第一次需要15秒,以下时间需要8秒。

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

所以我第二次有7秒的提升。

现在我再次运行应用程序(所以我做了一个新的数据库连接)第一次需要15秒,第二次是7 ...

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

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

3 个答案:

答案 0 :(得分:2)

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

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

SQL Server确实进行了自动参数化,但对此可能相当保守。

您可以从以下

了解计划重用
SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
where text like '%MYTasks%' and attribute='set_options'

答案 1 :(得分:2)

SQL Server将为您执行此操作 - 只要有可用空间,就会存储任何执行计划。

但是,您可以做很多事情来增加执行计划的存储和重用机会 - 您需要注意的是创建相同的 SQL查询 - 任何可能导致额外空间的事情都可能导致SQL Server认为两个查询不同,不重用现有的查询计划。

因此:

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

  • 使用参数而不是文字值;如果您使用文字值,您的查询计划将不会被重复使用,并且它们会不必要地填满计划缓存。

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

现在不用你的SQL,而是使用它:

SELECT (list of fields)
FROM dbo.MYTasks 
WHERE DATE < @EndDate and DATE > @StartDate

这应该会显着增加查询计划的重用。

答案 2 :(得分:0)

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

从您的问题描述中,额外的7秒可能是设置与数据库的初始连接的时间。也许你已经排除了这一点。我不知道。

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