快速选择有时会超时

时间:2015-06-26 09:11:20

标签: sql sql-server azure-sql-database

我有执行简单选择的存储过程。每次我手动运行它,它都会在第二次运行。但是在生产(SQL Azure S2数据库)中,它每12个我们的计划任务内部运行一次 - 所以我认为期望它每次都以“冷”运行是合理的 - 没有缓存数据。性能非常难以预测 - 有时需要5秒钟,有时甚至是30秒,有时甚至是100秒。

select被优化到最大值(我的知识,无论如何) - 我创建了包含从SELECT返回的所有列的过滤索引,因此执行计划中唯一的操作是索引扫描。估计行与实际行之间存在巨大差异:

enter image description here

但整体而言,查询看起来非常轻巧。我不怪责环境(SQL Azure),因为有很多查询一直在执行,而且这是唯一一个有此性能问题的查询。

这是SQL忍者愿意提供帮助的XML执行计划:http://pastebin.com/u5GCz0vW

编辑:

表格结构:

CREATE TABLE [myproject].[Purchase](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ProductId] [nvarchar](50) NOT NULL,
    [DeviceId] [nvarchar](255) NOT NULL,
    [UserId] [nvarchar](255) NOT NULL,
    [Receipt] [nvarchar](max) NULL,
    [AppVersion] [nvarchar](50) NOT NULL,
    [OSType] [tinyint] NOT NULL,
    [IP] [nchar](15) NOT NULL,
    [CreatedOn] [datetime] NOT NULL,
    [ValidationState] [smallint] NOT NULL,
    [ValidationInfo] [nvarchar](max) NULL,
    [ValidationError] [nvarchar](max) NULL,
    [ValidatedOn] [datetime] NULL,
    [PurchaseId] [nvarchar](255) NULL,
    [PurchaseDate] [datetime] NULL,
    [ExpirationDate] [datetime] NULL,
 CONSTRAINT [PK_Purchase] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)

索引定义:

CREATE NONCLUSTERED INDEX [IX_AndroidRevalidationTargets3] ON [myproject].[Purchase]
(
    [ExpirationDate] ASC,
    [ValidatedOn] ASC
)
INCLUDE (   [ProductId],
    [DeviceId],
    [UserId],
    [Receipt],
    [AppVersion],
    [OSType],
    [IP],
    [CreatedOn],
    [ValidationState],
    [ValidationInfo],
    [ValidationError],
    [PurchaseId],
    [PurchaseDate]) 
WHERE ([OSType]=(1) AND [ProductId] IS NOT NULL AND [ProductId]<>'trial' AND ([ValidationState] IN ((1), (0), (-2))))

数据可以被认为是敏感的,所以我无法提供样本。

1 个答案:

答案 0 :(得分:1)

由于您的查询只返回1个匹配项,因此我认为您应该将索引减少到最低限度。您可以通过聚簇索引中的Key Lookup获取剩余的列:

CREATE NONCLUSTERED INDEX [IX_AndroidRevalidationTargets3] ON [myproject].[Purchase]
(
    [ExpirationDate] ASC,
    [ValidatedOn] ASC
)
WHERE ([OSType]=(1) AND [ProductId] IS NOT NULL AND [ProductId]<>'trial' AND ([ValidationState] IN ((1), (0), (-2))))

这并没有消除扫描,但它使得索引更加精简,可以快速读取。

编辑: OP表示SQL Server忽略了精简的索引。您可以强制SQL Server使用筛选器索引:

SELECT *
FROM [myproject].[Purchase] WITH (INDEX(IX_AndroidRevalidationTargets3))