【发布时间】:2015-02-23 19:29:34
【问题描述】:
所以我有这个非常简单的 SP GetData,它有两个参数,看起来像这样
SET ANSI_NULLS ON
GO
SET QOUTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GetData]
@Id int = NULL,
@ExternalId nvarchar(500) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT
t.Id,
t.ExternalId,
t.Column1 -- other columns ommited for brevity
FROM [SomeTable] t
WHERE
(t.Id = @Id OR @ID IS NULL) AND
(t.ExternalId = @ExternalId OR @ExternalId IS NULL)
END
这很简单。一张表中只有一个选择语句。现在,我担心的是,如果我执行此过程,平均花费的时间为 0.505369 秒,但如果我提取该选择查询并执行它,查询平均需要 0.023923 秒。我真的很担心这一点,因为这个过程确实经常被调用,并且是我的应用程序中的关键过程之一,这就是为什么它现在如此最小化,0.5s 有点可以接受。这次该表仅包含 495 万行。 Id 列上有一个聚集索引,ExternalId 列上有一个非聚集索引。该表应该在即将到来的弱项中增加到 4500 万行,并且数据插入率会降低。在 4500 万行上,我认为上面显示的 SP 不会给出合理的时间。我真的不明白这里有什么问题,或者它应该是这样的?据我所知,在执行 SP 后,计划被缓存,下次不会重新创建计划,所以它应该比 on the fly query 快吗?在这种情况下,使用 Ad hoc 查询而不是 SP 更好吗?数据库是 Sql Server 2012。在此先感谢
【问题讨论】:
-
您应该拆分 4 种可能的情况以使用它们自己的查询或使用
OPTION (RECOMPILE)。第一个选项可能更可取,因为只有 4 种组合,而且您说它被频繁调用。 -
ExternalId字段的确切数据类型是什么?它的输入参数定义为NVARCHAR(500)。虽然该字段的类型和大小可能是正确的,但索引它超过了 900 字节的限制,所以我怀疑它真的是一个 NVARCHAR(500) 字段。 -
将参数@ExternalId 更改为varchar(60) 后,ExternalId 的数据类型为varchar(60) 对速度有任何影响。
标签: sql sql-server stored-procedures