我有一张桌子:
CREATE TABLE IF NOT EXISTS blacklist
(
id NUMERIC(20, 0) NOT NULL DEFAULT NEXTVAL('blacklist_sequence') PRIMARY KEY,
device_id VARCHAR(512) DEFAULT NULL NULL,
phone_number VARCHAR(512) DEFAULT NULL NULL
);
CREATE INDEX index_phone ON blacklist (phone_number);
CREATE INDEX index_device ON blacklist (device_id);
我想使用这个黑名单来查看是否有客户device_id
在phone_number
其中。所以我的查询是:
SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END
FROM blacklist b
JOIN
(SELECT id
FROM blacklist
WHERE device_id = :deviceId
UNION
SELECT id
FROM blacklist
WHERE phoneNumber = :phoneNumber) filtered_table ON b.id = filtered_table.id
基本上将OR
条件拆分为子查询UNION
以使用索引,但我发现我们有太多的黑名单行phone_number
填充了行,而使用device_id
.
所以,我正在寻找一种进一步并行化的方法,以便在device_id
找到匹配项时,我不必继续寻找收集和条件UNION
的结果phone_number
(因为那时我已经知道我SELECT
将返回TRUE
)到想出一个更大的COUNT
,因为我只对行是否存在感兴趣。
如何重写此查询以实现它?虽然我主要是在寻找 Postgres 解决方案,但我有兴趣了解其他数据库可以做什么。
您已经编写了查询,因此它必须找到每个匹配的行,然后再次查找该行以对其进行计数。您只需要使用
exists
谓词进行存在测试,一旦找到匹配项,它将立即返回。请参阅此 dbfiddle 以获取演示https://dbfiddle.uk/Awu5NUrI您可以看到第二个分支
union all
未执行,因为它在第一个分支中使用快速索引检查成功找到了匹配项。你不需要并行,你只需要做更少的工作。