【发布时间】:2014-01-19 09:45:10
【问题描述】:
table products
id primary_key
table transactions
product_id foreign_key references products
下面的SQL查询很慢:
SELECT products.*
FROM products
LEFT JOIN transactions
ON ( products.id = transactions.product_id )
WHERE transactions.product_id IS NULL;
在 100 亿条产品记录中,一个产品可能只有 100 条记录没有对应的交易。
此查询非常慢,因为我怀疑它正在执行全表扫描以查找那些空外键产品记录。
我想创建一个像这样的部分索引:
CREATE INDEX products_with_no_transactions_index
ON (Left JOIN TABLE
BETWEEN products AND transactions)
WHERE transactions.product_id IS NULL;
以上可能吗?我该怎么做?
注意: 该数据集的一些特征:
交易永远不会被删除,只会被添加。
产品永远不会被删除,而是以每分钟 100 秒的速度添加(显然这是一个复杂得多的实际用例背后的虚构示例)。其中一小部分是暂时的孤儿
我需要经常查询(最多每分钟一次)并且需要始终知道当前的孤立产品集是什么
【问题讨论】:
-
您可以在 products 表中添加“last_transaction_id”列,在插入时设置触发器,然后在 products 表中搜索 last_transaction_id 是否为空。
-
我试图不触及现有架构。创建索引是不可能的吗?或者,我可以创建任何索引,只要它不涉及更改架构或需要编写插入触发器
-
实际上,只要我能快速查找,我可以接受不涉及更改架构的任何事情
-
FK 约束自动为 product_id 列构建索引。但是:您正在寻找孤立的行,这需要时间。它们可以放在任何地方,至少必须查阅整个索引加上产品表(或它的索引)才能找到它们。您正在 100M 的大海捞针中寻找一百根针。你为什么要找到它们,如果这是你的核心逻辑的一部分,那么你的数据模型中的某些东西是严重错误的,恕我直言。如果只是维护:处理它。
-
我冒昧地根据您的问题修复查询以匹配您的表定义。
标签: sql postgresql indexing materialized-views postgresql-performance