Postgresql
並行和更快地評估 SELECTing 布爾比較計數
我有一張桌子:
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
未執行,因為它在第一個分支中使用快速索引檢查成功找到了匹配項。你不需要並行,你只需要做更少的工作。
select 1 where exists (select null from blacklist where phone_number = :phone_number union all select null from blacklist where device_id = :device_id )