2017-10-11 104 views
2

假設你有一些指標表:PostgreSQL - 它會在同一個表上使用兩個索引嗎?

create table mail 
(
    identifier serial primary key, 
    member text, 
    read boolean 
); 

create index on mail(member_identifier); 
create index on mail(read); 

如果你現在上有單獨的索引多列查詢,將它曾經用這兩個指數?

select * from mail where member = 'Jess' and read = false; 

也就是說,可以PostgreSQL的決定了首先使用member的索引取了傑斯的所有郵件,然後使用上read索引來獲取所有封未讀郵件,然後相交兩個結果構造輸出設置?

我知道你可以有多列索引(在這種情況下,在(member, read)),但如果你有兩個單獨的索引會發生什麼? PostgreSQL會選擇一個還是可以在某些情況下使用它們?

這不是關於特定查詢的問題。理解內部是一個通用的問題。

+0

爲查詢發佈EXPLAIN。 –

+0

@RaymondNijland這個問題不是關於特定的查詢,而是更多的一個通用的問題來理解內部。 –

回答

5

Postgres Documentation about multiple query indexes

文章說,它會創建的其中兩個指標應用,然後合併結果的抽象表示。

要結合多個索引,系統掃描每個需要的指數, 準備在內存中的位圖給予該 報告爲匹配指數的條件錶行的位置。位圖然後按照查詢的需要與 進行「並(OR)」或「或(OR)」。最後,訪問並返回實際的 表格行。

+0

另請參閱[本文](https://devcenter.heroku.com/articles/postgresql-indexes#multi-column-indexes)。 –

3
CREATE TABLE fifteen 
     (one serial PRIMARY KEY 
     , three integer not NULL 
     , five integer not NULL 
     ); 

INSERT INTO fifteen(three,five) 
SELECT gs%33+5,gs%55+11 
FROM generate_series(1,60000) gs 
     ; 

CREATE INDEX ON fifteen(three); 
CREATE INDEX ON fifteen(five); 
ANALYZE fifteen; 

EXPLAIN ANALYZE 
SELECT* 
FROM fifteen 
WHERE three= 7 
AND five =13 
     ; 

結果:


CREATE TABLE 
INSERT 0 60000 
CREATE INDEX 
CREATE INDEX 
ANALYZE 
                   QUERY PLAN                
--------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on fifteen (cost=19.24..51.58 rows=31 width=12) (actual time=0.391..0.761 rows=364 loops=1) 
    Recheck Cond: ((five = 13) AND (three = 7)) 
    Heap Blocks: exact=324 
    -> BitmapAnd (cost=19.24..19.24 rows=31 width=0) (actual time=0.355..0.355 rows=0 loops=1) 
     -> Bitmap Index Scan on fifteen_five_idx (cost=0.00..7.15 rows=1050 width=0) (actual time=0.136..0.136 rows=1091 loops=1) 
       Index Cond: (five = 13) 
     -> Bitmap Index Scan on fifteen_three_idx (cost=0.00..11.93 rows=1788 width=0) (actual time=0.194..0.194 rows=1819 loops=1) 
       Index Cond: (three = 7) 
Planning time: 0.259 ms 
Execution time: 0.796 ms 
(10 rows) 

更改{33,55}到{3,5}將產生索引掃描僅在一個索引,加一個附加的過濾條件。 (可能節省的費用太少)

相關問題