C# API 从 PostgreSQL 获取数据时出现超时异常和瞬态失败

问题描述 投票:0回答:1

我正在开发一个 C# API,使用 pgAdmin4 从 PostgreSQL 数据库中的多个表中获取数据。但是,我不断遇到以下错误:

瞬时故障: {“出现了异常,可能是由于暂时性故障所致。”}

超时异常: 尝试读取超时

这是我的代码的相关部分:

var images = _staticDataContext.HotelContentImages
    .Where(i => hotelContentIds.Contains(i.HotelContentId))
    .ToList();

其他房间等如图片 hotelContentIds 是一个包含 3 或 5 个 GUID 的小列表。 每个查询都从不同的表(HotelContentImages 和 HotelContentRooms)获取数据。 这些表有 200 多行。

即使我尝试从 pgadmin 数据库获取数据,也需要很长时间才能给出输出。我应该做什么才能更快地得到结果。

c# postgresql api
1个回答
0
投票

首先:ofcurse您需要确保数据库中的相关列已建立索引 例如,您的 HotelContentImages 表有 HotelContentId 你需要这样做

CREATE INDEX idx_hotel_content_id ON HotelContentImages(HotelContentId);

不用担心这不会影响您的数据,它只是编辑您的架构。

其次:你可以使用PostgreSQL设计的简单查询
真空分析; 这个查询做了两件重要的事情

  1. VACUUM:这会回收死元组(已更新或删除的行)占用的存储空间
  2. ANALYZE:这会更新查询规划器使用的统计信息。 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

我认为如果你做了所有这些事情,你将永远不会面临任何失败

© www.soinside.com 2019 - 2024. All rights reserved.