索引如何影响存储过程的性能

时间:2014-05-01 13:35:59

标签: sql sql-server-2008 stored-procedures

我正在使用SQL Server 2008。

我有两张这样的表:

Location_tbl结构是这样的:

 Locid    int 
 LocName  varchar(150)

Locid是主键

TrTransaction_tbl结构是这样的:

transactID    int
TBarcode      varchar(20)
Locid         int
PlateNo       varchar(20)
dtime         datetime
DelEcode      nvarchar(50)
Paydate       datetime
KeyRoomDate   datetime
DelDate       datetime
Status        int

在此表中,transactID是主键,locid是外键。

在事务表中,我有超过20万行,每天增加大约30 000条记录。我还没有在我的事务表上实现任何索引..所以我的存储过程执行需要很长时间。

我在TrTransaction_tbl.locid添加了一个索引,如下所示:

create index transactlocid on transaction_tbl (Locid asc)

我想知道这个索引是否有助于我的存储过程运行得更快?

这会影响表格或记录中的任何内容吗?

这是我的存储过程:

ALTER procedure [dbo].[IBS_fetchreqVehicleinPodiumtestnew1]
   @locid INTEGER = NULL
AS BEGIN
   SET NOCOUNT ON

   DECLARE @TodayMinus7Days DATETIME
   Declare @krrt integer
   Declare @DT integer
   SET @TodayMinus7Days = getdate()-1

   SELECT  
       t.TBarcode, t.PlateNo, t.DelEcode,
       datediff(MINUTE, t.PayDate,
             CASE t.Status
                WHEN 3 THEN GETDATE()
                WHEN 4 THEN t.KeyRoomDate
                When 5 THEN  t.KeyRoomDate
                End) as KRRT,

             datediff(MINUTE,t.PayDate,
             CASE t.Status
              WHEN 3 THEN GETDATE()
              WHEN 4 THEN GETDATE()
             WHEN 5 THEN t.DelDate
             END) as DT

   FROM    
       dbo.Transaction_tbl t
   WHERE   
       ([status] IN (3,4) AND locid = @locid AND dtime >= @TodayMinus7Days)
       OR 
       ([status] = 5 AND DATEDIFF(n, CAST(DelDate AS DATETIME), GETDATE()) <= 3
         AND locid = @locid AND dtime >= @TodayMinus7Days)
   ORDER BY  
       paydate
       end

如果我创建这样的索引:

CREATE INDEX IX_TRANSACTION ON transaction_tbl
(
    Locid ASC, DTime ASC, Status ASC, DelDate ASC
)

这个 dtime 意味着,,,我花了当前时间保存每条记录,如果我给这个索引,我的插入会慢一点吗?

2 个答案:

答案 0 :(得分:1)

我非常怀疑该指数会有所帮助。没有查询计划真的无法判断,但您可以尝试这样的索引:

CREATE INDEX IX_TRANSACTION ON transaction_tbl
(
    Locid ASC, DTime ASC, Status ASC, DelDate ASC
)

此索引将允许WHERE子句条件完全从索引中解析。理想情况下,它将搜索LocId和DTime,然后谓词 - 解析Status和DelDate。然后它仍然必须返回并查找主表中的其余列(因此,根据它所期望的匹配数,它仍然可以跳过此索引,但我需要查询计划来告诉它)。


正如HLGEM在评论中指出的那样,DelDate已经已经一个DATETIME,因此无需转换它。所以下面的where子句应该更好用:

WHERE   locid = @locid
  AND   dtime >= @TodayMinus7Days
  AND   (( [status] IN (3,4) )
      OR 
         ([status] = 5 AND DATEDIFF(n, DelDate, GETDATE()) <= 3)
        )

答案 1 :(得分:0)

因为您在locid上添加了一个索引,并且您的WHERE子句分支在locid上都有一个特定的过滤器,优化器能够显着提高性能这个查询。

如果没有,我会建议从locid = @locid构造中“分解”OR子句;如果它变得混乱,这可能对优化器有所帮助。

当然,打开SSMS中的“显示实际执行计划”选项是一个好主意,看看它是否产生了一个好的计划。如果您发布计划的屏幕截图,我们可能会看到您是否获得了所需的改进,或者是否还有其他可以完成的工作。