Postgresql

並行和更快地評估 SELECTing 布爾比較計數

  • September 10, 2022

我有一張桌子:

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_idphone_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
 )

引用自:https://dba.stackexchange.com/questions/316735