我在 Postgres 中有一个小型数据库,大约有 10,000 条记录存储公司客户。
我有一个执行非常频繁的“缓慢”执行查询(大约半秒),我的老板希望我改进它。
首先 - 我的代码:
select customer_alias.id, customer_alias.name, site.address, phone.phonenumber
from customer_alias
join customer on customer_alias.customer_id = customer.id
left join site on customer.default_site_id = site.id
left join contact_phonenumbers as phone on site.default_phonenumber = phone.id
Run Code Online (Sandbox Code Playgroud)
(编辑left join customer
为join customer
)
让我突然customer
想到的是,即使我没有从该记录中选择任何内容,我也正在执行连接。我目前必须加入它才能获得表default_site_id
的外键site
。
每个客户可以有多个站点,但此列表中只能显示一个站点(必须打开一个客户才能查看所有站点)。所以我的问题是,如果我无法优化查询,是否有不同的方式可以为特定客户存储默认站点?默认电话号码也是如此
一个客户可以有多个站点,但一个站点只有一个客户(多对一)。
EXPLAIN
返回:
Hash Join (cost=522.72..943.76 rows=5018 width=53)
Hash Cond: (customer.id = customer_alias.customer_id)
-> Hash Right Join (cost=371.81..698.77 rows=5018 width=32)
Hash Cond: (site.id = customer.default_site_id) …
Run Code Online (Sandbox Code Playgroud) 我正在将 Web 应用程序从 SqlServer 迁移到 PostgreSQL,并且我正在尝试找出要替换的类型datetime2
。
一般的建议似乎是总是使用timestamptz
,以及从不使用timestamp
。给出的原因往往是时间戳和timestamptz
存储相同(因此没有性能损失)并timestamptz
自动转换为连接的时区。在 Rails 和 PostgreSQL 中完全忽略时区 | 堆栈溢出
不幸的是,我的旧版 .NET 代码库与日期时间非常不一致,我们通常以 UTC 进行渲染,而不管用户时区如何。最近的代码一直在使用 NodaTime 及其Instant
类,但我们很少需要处理时间并且仅显示日期已经“足够接近”。然而,我对正确使用 NodaTime 的理解是尽可能晚地将 转换Instant
为,而不是在数据库中。LocalDateTime
除此之外,我不完全确定 Postgres 如何知道“当前用户”的正确时区。我知道您可以专门将时区设置为会话参数SET TIME ZONE 'UTC';
,您是否希望为每个连接执行此操作以适合“当前用户”?如果是这样,每当从连接池检索连接时都会重置它吗?我还看到 Npgsql 能够为连接字符串设置时区,如果是针对每个用户,这可能是不合适的?
所有这些使我认为最好的选择是用于timestamp
所有日期时间,并使用应用程序逻辑转换为本地日期时间。我想另一个选择是用于timestamptz
所有日期时间,强制连接在连接字符串中使用 UTC,并使用应用程序逻辑转换为本地日期时间。但是我担心 Postgres 会在 UTC 和 UTC 之间进行无操作转换时执行额外的工作。
TLDR:timestamptz
如果应用程序始终插入/读取 UTC 并转换为本地日期时间本身,这仍然是首选吗?