查询不活动后的Azure SQL超时

时间:2018-11-25 20:14:12

标签: azure azure-sql-database azure-sql-managed-instance

我的托管Azure SQL实例频繁超时。如果一段时间没有查询活动发生,则预计将在500-2000行之间返回的第一个查询将使用我的定价层(S2 50 DTU计划)中所有可用的DTU,并且始终导致以下异常:< / p>

System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (258): The wait operation timed out
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
ClientConnectionId:903324e4-4eba-4522-bae8-228a23c0e51c
Error Number:-2,State:0,Class:11
ClientConnectionId before routing:24ca7fb2-4c3b-44ad-b393-d8cda9dda172

此后立即执行相同的查询时,服务器将立即响应。可能是因为最近的查询已加载到内存中。 SQL Server在物联网设置中使用,因此从一天开始不断发生来自设备的数据流传输(大容量插入)。我试图通过让Azure函数每小时执行一次查询以将频繁访问的数据加载到内存中来解决问题,但这只会解决我正在Azure函数中查询的特定实体的问题。根据执行计划,我所有的查询都使用正确的索引。

我认为实施重试策略不是可接受的解决方案。在我看来,这只会进一步降低用户体验。有人在这个问题上有经验吗?

编辑: 这里的执行计划: https://www.brentozar.com/pastetheplan/?id=rJQvb7tRm

1 个答案:

答案 0 :(得分:1)

实际执行计划显示DeviceUniqueIdentifier聚集索引键上的聚集索引搜索读取了1187行,即使没有行满足其他条件。将InstanceIdNVEControllerTimestamp添加到聚簇索引键将避免不必要地触摸这些行。

通常,支持返回所有列的平凡查询的最佳索引是聚簇索引,其聚类谓词键列先于(DeviceUniqueIdentifierInstanceId),然后是不等式列(范围搜索为NVEControllerTimestamp)。

您可以使用CREATE INDEX...WITH (DROP_EXISTING = ON)将其他列添加到现有的聚集索引中。