我使用的是 PostgreSQL 数据库,有 4 个表可供使用:registry、invoice、invoice_position、user_involved
表注册表列:
id
reg_name
表格发票:
id
reg_id(FK to registry, can be many invoices in one registry)
invoice_name
表invoice_position:
id
invoice_id(FK to invoice, can be many positions in invoice)
position_name
表 user_involved:
id
Inv_position_id(FK to invoice_position, it's a one to one relationship)
user_name
我需要创建一个 SELECT 查询,如果 registry 表中出现不止一次 user_involved(这仅与 user_involved 相关,由 FK 的 invoice_position ->发票->注册)。需要注意的几件事是,这些表每个包含超过 +/- 1.000.000 行(注册表表除外),此时我无法在注册表和 user_involved 之间添加直接关系。问题是如何编写最佳 SELECT,或者在这种状态下是否有可能,因为嵌套多个 SELECT 将花费很长时间。
编辑: 到目前为止,这是我尝试过的:
SELECT rg.id, COUNT(ui.id) FROM registry rg
LEFT JOIN invoice inv ON inv.reg_id = rg.id
LEFT JOIN invoice_position ip ON ip.invoice_id = inv.id
LEFT JOIN user_involved ui ON ui.inv_position_id = ip.id
WHERE ip.id = $id GROUP BY rg.id,ui.id HAVING COUNT (ui.id) > 1;
此查询将在一个 while 循环内,其中带有给定不同发票位置 ID 的变量“id”。
最佳答案
我会先做:
EXPLAIN
SELECT rg.id, COUNT(ui.id)
FROM invoice_position ip, invoice inv, registry rg, user_involved ui
WHERE ip.id = $id
AND ip.invoice_id = inv.id
AND inv.reg_id = rg.id
AND ui.inv_position_id = ip.id
GROUP BY rg.id
HAVING COUNT(ui.id) > 1;
看看你得到了什么。不使用 LEFT OUTER JOIN
的原因是它们限制了优化器可以选择的计划(或者至少他们在我上次检查时做了)并且这个查询似乎没有需要他们。
除此之外,您还可以考虑一次获取多个 invoice_position
行并在数据库外部进行匹配。这样您就可以稍微分摊执行查询的成本,但代价是调用代码会更复杂一些。
例如:
SELECT ip.id, rg.id, COUNT(ui.id)
FROM invoice_position ip, invoice inv, registry rg, user_involved ui
WHERE ip.id IN $id_list
AND ip.invoice_id = inv.id
AND inv.reg_id = rg.id
AND ui.inv_position_id = ip.id
GROUP BY ip.id, rg.id
HAVING COUNT(ui.id) > 1;
关于sql - 具有许多表的 PostgreSQL 最佳 SELECT 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53593777/