我正在开发一个 C# API,使用 pgAdmin4 从 PostgreSQL 数据库中的多个表中获取数据。但是,我不断遇到以下错误:
瞬时故障: {“出现了异常,可能是由于暂时性故障所致。”}
超时异常: 尝试读取超时
这是我的代码的相关部分:
var images = _staticDataContext.HotelContentImages
.Where(i => hotelContentIds.Contains(i.HotelContentId))
.ToList();
其他房间等如图片 hotelContentIds 是一个包含 3 或 5 个 GUID 的小列表。 每个查询都从不同的表(HotelContentImages 和 HotelContentRooms)获取数据。 这些表有 200 多行。
即使我尝试从 pgadmin 数据库获取数据,也需要很长时间才能给出输出。我应该做什么才能更快地得到结果。
首先:ofcurse您需要确保数据库中的相关列已建立索引 例如,您的 HotelContentImages 表有 HotelContentId 你需要这样做
CREATE INDEX idx_hotel_content_id ON HotelContentImages(HotelContentId);
不用担心这不会影响您的数据,它只是编辑您的架构。
其次:你可以使用PostgreSQL设计的简单查询
真空分析;
这个查询做了两件重要的事情
如果你有一个巨大的桌子,运行
VACUUM ANALYZE HotelContentImages;
会更好,因为这仅关注您需要的表格。
第三:在ORM层面你可以使用Eager Loading 您可以通过使用 Include 加载相关数据来减少多次数据库往返,以您的示例为例,您可以执行以下操作:
var images = _staticDataContext.HotelContentImages
.Include(i => i.AnyRelatedTable)
.Where(i => hotelContentIds.Contains(i.HotelContentId))
.ToList();
第四:您还可以使用异步查询来避免阻塞线程:
var images =await _staticDataContext.HotelContentImages
.Include(i => i.AnyRelatedTable)
.Where(i => hotelContentIds.Contains(i.HotelContentId))
.ToListAsync();
第 5 :确保在连接字符串中配置连接池:
"Host=yourserver;Database=yourdb;Username=youruser;Password=yourpass;Pooling=true;MaxPoolSize=100;"
第六:也许连接网络本身有问题,所以尝试通过名为 Polly
的库进行日志记录var retryPolicy = Policy
.Handle<Exception>() // Specify transient failure exceptions
.WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
retryPolicy.Execute(() =>
{
var images = _staticDataContext.HotelContentImages
.Where(i => hotelContentIds.Contains(i.HotelContentId))
.ToList();
});
最后:您还可以增加命令超时时间
_staticDataContext.Database.SetCommandTimeout(120); // 120 seconds
我认为如果你做了所有这些事情,你将永远不会面临任何失败