我有一个包含60个表的数据库。一个是表person
,该表还被大量其他表(大约40个)引用,大部分使用ON DELETE CASCADE ON UPDATE CASCADE
。
使用Npgsql,我尝试运行以下命令:
DELETE FROM person WHERE id = @PersonId
结果是我收到System.IO.Exception:
Npgsql.NpgsqlException(0x80004005):从流中读取时发生异常---> System.IO.IOException:Von derÜbertragungsverbindungkönnenkeine Daten gelesen werden:Ein Verbindungsversuch ist fehlgeschlagen,Gegenstelle nach hatitspannermm ,或从hergestellte Verbindung战役中撤离,由und verbundene主持人提供。 ---> System.Net.Sockets.SocketException:Ein Verbindungsversuch ist fehlgeschlagen,Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat,oder die hergestellte Verbindung war fehlerhaft,da der verbundene Host nicht reagiert hatt bei System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags) bei System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小) --- Ende der internenAusnahmestapelüberwachung--- bei System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小) bei Npgsql.NpgsqlReadBuffer。<> c__DisplayClass31_0。
d.MoveNext() bei Npgsql.NpgsqlReadBuffer。<> c__DisplayClass31_0。 d.MoveNext() --- Ende derStapelüberwachungvom vorhergehenden Ort,奥斯曼·奥斯格洛斯特·伍德 bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) bei Npgsql.NpgsqlConnector。<> c__DisplayClass161_0。 d.MoveNext()
在英语中,内部例外是
Npgsql.NpgsqlException(0x80004005):从中读取时发生异常 流---> System.IO.IOException:无法从 传输连接:连接尝试失败,因为 一段时间后,远程站未正确响应 时间或建立的连接有问题,因为连接的主机 没有回应。 ---> System.Net.Sockets.SocketException:连接 尝试失败,因为远程站未正确响应 经过一定时间后,或者连接失败,原因是 连接的主机未响应System.Net.Sockets。 Socket.Receive(字节[]缓冲区,Int32偏移量,Int32大小,SocketFlags System.Net.Sockets.NetworkStream.Read中的socketFlags)(字节[]缓冲区, Int32偏移量,Int32大小)---内部异常堆栈跟踪结束
在Postgres日志中显示:
2019-03-28 12:42:15.077 CET [75060]日志:konnte Daten vom Client nicht empfangen:无法识别的winsock错误10053
我想这不是死锁,因为日志中没有死锁消息。
我认为这与表被众多外键引用这一事实有关。但是我不知道如何进一步调查。
答案 0 :(得分:3)
作为例外,此问题与长时间运行的脚本超时有关。您没有包括代码示例,因此我无法专门提供语法来增加此示例,但是设置commandTimeout = 0
将禁用超时并解决问题。
要在评论中解决您的问题,
有什么方法可以调查为什么需要这么长时间?
它可能只是删除大量记录。您应该在C#之外运行查询,以确保在将查询插入代码之前对查询进行了优化。
删除大量记录可能需要一段时间,您应该研究truncate
或其他清除设计,例如转储到临时表等。
答案 1 :(得分:1)
我的钱花在引用person
的外键上缺少索引上。
如果您有一个这样的表:
CREATE TABLE atable (
id bigint PRIMARY KEY,
parent_id bigint NOT NULL
REFERENCING parent ON DELETE CASCADE
);
,并且该表包含很多行,那么在person
中删除的每一行将导致对atable
进行顺序表扫描以找到匹配的行。那可能就是您所有时间都用在的地方。
在所有引用person
的表上创建索引:
CREATE INDEX ON atable (parent_id);
这将使删除速度更快。
This blog post详细说明了问题。