npgsql - Npgsql C# wcf 应用程序在 command.ExecuteReader() 上挂起
问题描述
多线程 npgsql 应用程序遇到我每次都可以重现的数据库问题。
对应用程序运行 3 个并行登录请求会破坏应用程序的稳定性,然后当我发送批处理(运行多个查询)时,一些 ExecuteReader 会挂起。
只有在 CommandTimeout 到期(60 秒)时,对 command.ExecuteReader() 的调用才会返回。
挂起调用的堆栈跟踪:
[Managed to Native Transition]
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) Unknown
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) Unknown
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size) Unknown
Npgsql.dll!Npgsql.NpgsqlReadBuffer.Ensure.__EnsureLong|0() Line 150 C#
Npgsql.dll!Npgsql.NpgsqlReadBuffer.Ensure(int count, bool async, bool dontBreakOnTimeouts) Line 116 C#
Npgsql.dll!Npgsql.NpgsqlConnector.ReadMessage.__ReadMessageLong|0(Npgsql.DataRowLoadingMode dataRowLoadingMode2, bool readingNotifications2, bool isReadingPrependedMessage) Line 954 C#
Npgsql.dll!Npgsql.NpgsqlConnector.ReadMessage(bool async, Npgsql.DataRowLoadingMode dataRowLoadingMode, bool readingNotifications) Line 923 C#
Npgsql.dll!Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming) Line 444 C#
[Resuming Async Method]
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<bool>.Start<Npgsql.NpgsqlDataReader.<NextResult>d__46>(ref Npgsql.NpgsqlDataReader.<NextResult>d__46 stateMachine) Unknown
Npgsql.dll!Npgsql.NpgsqlDataReader.NextResult() Line 332 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteDbDataReader(System.Data.CommandBehavior behavior, bool async, System.Threading.CancellationToken cancellationToken) Line 1218 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteDbDataReader(System.Data.CommandBehavior behavior) Line 1130 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteReader(System.Data.CommandBehavior behavior) Line 1111 C#
> xyz.PostgresDBConnection.ExecReader(Npgsql.NpgsqlCommand comm) Line 279 C#
解决方案
事实证明,罪魁祸首是以下极其缓慢的查询(在具有 31259 行的表上):
SELECT Item.id, Item.data FROM Item
INNER JOIN Item AS it ON item.id = Item.id AND item.data = Item.data
AND item.data2 <> Item.data2 LIMIT 1
然而,Npgsql 并没有停留在这个查询上,而是一个不同的查询,但原因是这个查询。
我用不同的等效查询替换了它:
SELECT Item.id, Item.data FROM Item
GROUP BY Item.id, Item.data
HAVING COUNT(DISTINCT Item.data2) > 1
LIMIT 1
问题似乎得到了解决。
推荐阅读
- regex - EGREP 命令打印包含四个字母的子字符串的所有行
- javascript - 调度 KeyboardEvent 无法在文本区域中生成字符
- angular - Angular 6 使用带有配置服务的 Http 拦截器
- java - Java PIT 类路径问题
- c# - 数据表到 eventthub 并超出限制
- version-control - Kubernetes 资源版本控制
- testing - CSV 数据集:参数化 JMeter 中的 URL 变量 - 错误的 CSV 文件
- json - 创建本地邮箱订阅时出现“状态代码:未找到;原因:未找到”
- google-maps - Flutter map_view 中的样式 poi
- docker - 在 Windows Server 2016 上构建 Docker 映像