9

在 SQL Azure 中,我或多或少地设置了一个表,其中包含两个计算列(IsExpiredIsDeadlineExpired),它们只是将不可为空的日期时间列与当前时间进行比较:

CREATE TABLE [dbo].[Stuff]
(
   [StuffId] int NOT NULL IDENTITY(1,1),
   [Guid] uniqueidentifier NOT NULL,
   [ExpirationDate] datetime NOT NULL,
   [DeadlineDate] datetime NOT NULL,
   [UserId] int NOT NULL,
   [IsExpired] AS CAST((CASE WHEN [ExpirationDate] < GETUTCDATE() THEN 1 ELSE 0 END) AS bit),
   [IsDeadlineExpired] AS CAST((CASE WHEN [DeadlineDate] < GETUTCDATE() THEN 1 ELSE 0 END) AS bit),
   CONSTRAINT [PK_StuffId] PRIMARY KEY ([StuffId]),
   CONSTRAINT [UNQ_Guid] UNIQUE([Guid]),
)
GO

我有一个包含多个结果集的存储过程,其中一个拉取:

SELECT * FROM [dbo].[Stuff] WHERE [Guid] = @guid

我最近注意到错误日志表明有时当使用 读取结果集时SqlDataReaderSqlDataReader.GetOrdinal("IsExpired")使用IndexOutOfRangeException. 我知道即使在这些情况下,前面的列也可以正常工作,因为它们是在前面的代码行中读取的,没有错误。我也相信该过程的结果集是按正确的顺序排列的,因为它们不共享列名(否则读取前面的列同样会失败)。

另外:大多数时候一切似乎都很完美。

这可以以某种方式归因于 Azure 瞬态故障吗?

4

2 回答 2

1

请参考这篇文章:SELECT * AND SQL Azure

其作者强烈建议更换

SELECT *
FROM TableName

SELECT [Column1], [Column2], ... [ColumnN]
FROM TableName

因为使用 SELECT * 可能会导致额外的分页、RFID 查找、不需要的表锁定并阻碍将来创建覆盖索引的任何尝试。总而言之,它对性能不利

顺便说一句:这里有一组有趣的文章:

  1. 如何获取 SQL Azure 查询性能数据
  2. 查询性能
  3. 适用于 Visual Studio 的 Windows Azure 工具入门
  4. SQL Azure 开发入门
  5. 提高 I/O 性能
  6. 使用 SQL Azure 分析查询性能变得更加容易。

我怀疑GetOrdinary("IsExpired")由于 MS SQL Azure 框架的上述行为而导致System.IndexOutOfRangeException 。

结论?使用带有定义的列列表的SELECT语句来提高 SQL Azure 数据库的性能并避免 IndexOutOfRange 异常。

于 2013-12-30T08:09:58.780 回答
0

查看一些旧日志,得出的结论是,只有在同时部署 DACPAC 时查询运行时才会发生此错误(作为我们对这个特定测试环境的自动部署的一部分)。

我假设架构在 DACPAC 部署期间不一定处于可靠状态。

从那时起,我们添加了一些代码,以便在部署期间将应用程序置于“维护模式”(即使是这些自动化模式)。这似乎缓解了这个问题。

于 2016-04-05T21:20:15.590 回答