2016-02-26 40 views
0

有一個測試表是這樣的:Postgres沒有使用索引超過一定的行數限制?

testdb=> \d test_table 
              Table "public.test_table" 
      Column   |   Type    |       Modifiers 
----------------------------+-----------------------------+----------------------------------------------------------- 
id       | integer      | not null default nextval('test_table_id_seq'::regclass) 
phone      | character varying(15)  | not null 
comment     | text      | 
timestamp     | timestamp without time zone | not null 
Indexes: 
    "test_table_pkey" PRIMARY KEY, btree (id) 
    "i_test_substr" btree ("substring"(phone::text, 1, 1), "timestamp" DESC) 
Triggers: 

有了這樣一個指標:

testdb=> create index i_test_substr ON test_table (substring(phone, 1, 1), timestamp desc); 

這些查詢將使用該索引下的203行的限制進行排序,但排序內存204行以上。

任何人都可以解釋這種行爲嗎?

testdb=> explain analyze select * from test_table where substring(phone,1 ,1) = '2' order by timestamp desc limit 203; 
                   QUERY PLAN 
------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.42..709.52 rows=203 width=202) (actual time=0.043..0.194 rows=203 loops=1) 
    -> Index Scan using i_test_substr on test_table (cost=0.42..1146.16 rows=328 width=202) (actual time=0.041..0.170 rows=203 loops=1) 
     Index Cond: ("substring"((phone)::text, 1, 1) = '2'::text) 
Total runtime: 0.249 ms 
(4 rows) 



testdb=> explain analyze select * from test_table where substring(phone,1 ,1) = '2' order by timestamp desc limit 204; 
                   QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=711.74..712.25 rows=204 width=202) (actual time=7.655..7.681 rows=204 loops=1) 
    -> Sort (cost=711.74..712.56 rows=328 width=202) (actual time=7.653..7.664 rows=204 loops=1) 
     Sort Key: "timestamp" 
     Sort Method: top-N heapsort Memory: 53kB 
     -> Bitmap Heap Scan on test_table (cost=10.96..698.03 rows=328 width=202) (actual time=1.340..5.010 rows=11514 loops=1) 
       Recheck Cond: ("substring"((phone)::text, 1, 1) = '2'::text) 
       -> Bitmap Index Scan on i_test_substr (cost=0.00..10.88 rows=328 width=0) (actual time=1.217..1.217 rows=11514 loops=1) 
        Index Cond: ("substring"((phone)::text, 1, 1) = '2'::text) 
Total runtime: 7.746 ms 
(9 rows) 
+0

請附上您的表格和查詢行數的粒度沒有限制+解釋分析沒有限制 –

+0

'vacuum','analyse','reindex'沒有幫助嗎? – devanand

+0

這就是優化器的工作原理。請參閱Bruce Momjan關於此的幻燈片,網址爲https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjCl9G05JXLAhVJDxoKHRfCAQcQFgggMAA&url=https%3A%2F%2Fmomjian.us%2Fmain %2Fwritings%2Fpgsql%2Foptimizer.pdf&USG = AFQjCNGDzCTCJt0n7BTrr_nqgfZIQMAUWQ&SIG2 = k_gYi_rSo3J-SvSel1saqA – greg

回答

0

簡而言之,在行數太多的情況下使用索引掃描會變得非常昂貴。索引掃描會爲每一行加載磁盤頁面,以使它們出現在索引中。因此一些頁面將被加載多次(可能多次)。位圖索引掃描首先製作一系列磁盤頁面,然後只加載一次。

因此,優化器計算每個可能的計劃的成本,並決定哪一個是最便宜的。

相關問題