2012-09-11 15 views
0

我對這個狀態感到非常疑惑,我發現查詢表 a,其中一個沒有索引列的條件是「極限1」,非常快,但列沒有索引,下面是一個例子:PostgreSQL:爲什麼使用「限制1」的無索引列的條件查詢表的速度非常快?

--1創建測試表20000000個數據

francs=> create table test_limit (id int4,name varchar(32)); 
CREATE TABLE 

francs=> insert into test_limit select generate_series(1,20000000),generate_series(1,20000000) || 'a'; 
INSERT 0 20000000 

francs=> \d test_limit; 
     Table "francs.test_limit" 
Column |   Type   | Modifiers 
--------+-----------------------+----------- 
id  | integer    | 
name | character varying(32) | 

--2查詢表

francs=> explain analyze select * from test_limit where id=1; 
               QUERY PLAN             
------------------------------------------------------------------------------------------------------------- 
Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.028..3162.477 rows=1 loops=1) 
    Filter: (id = 1) 
Total runtime: 3162.531 ms 
(3 rows) 

通知大約需要3162毫秒whihc很慢,因爲我期望的那樣。

--3查詢表「限制1」的原因

francs=> explain analyze select * from test_limit where id=1 limit 1; 
                QUERY PLAN             
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.019..0.019 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.017..0.017 rows=1 loops=1) 
     Filter: (id = 1) 
Total runtime: 0.047 ms 
(4 rows) 

注意到它只需約0.047毫秒毫秒,它是如此之快,但列ID沒有索引。任何身體可以解釋它? 非常感謝!

--4 addtion測試

francs=> explain analyze select * from test_limit where id=2 limit 1; 
                QUERY PLAN             
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.023..0.023 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.022..0.022 rows=1 loops=1) 
     Filter: (id = 2) 
Total runtime: 0.066 ms 
(4 rows) 

francs=> explain analyze select * from test_limit where id=3 limit 1; 
                QUERY PLAN             
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.022..0.022 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.021..0.021 rows=1 loops=1) 
     Filter: (id = 3) 
Total runtime: 0.060 ms 
(4 rows) 

francs=> explain analyze select * from test_limit where id=101 limit 1; 
                QUERY PLAN             
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.035..0.036 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.033..0.033 rows=1 loops=1) 
     Filter: (id = 101) 
Total runtime: 0.075 ms 
(4 rows) 

francs=> explain analyze select * from test_limit where id=1001 limit 1; 
                QUERY PLAN             
---------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.192..0.192 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=0.190..0.190 rows=1 loops=1) 
     Filter: (id = 1001) 
Total runtime: 0.231 ms 
(4 rows) 

從addtion測試中,我們可以看到它的速度也非常快。

--5最終測試

francs=> explain analyze select * from test_limit where id=9999999 limit 1; 
                 QUERY PLAN              
---------------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.00..358111.05 rows=1 width=13) (actual time=1379.153..1379.154 rows=1 loops=1) 
    -> Seq Scan on test_limit (cost=0.00..358111.05 rows=1 width=13) (actual time=1379.151..1379.151 rows=1 loops=1) 
     Filter: (id = 9999999) 
Total runtime: 1379.206 ms 
(4 rows) 

從上面的,我使用後的ID是9999999,它現在是緩慢的;我現在明白了,謝謝!

+0

我相信這是純屬運氣,因爲你的DB標誌着這是「完成」只要找到一個結果(限1),並把它放掉,並沒有限制人們仍然必須檢查留下的每一行。如果您使用的hihger ID超過1(最高ID),那麼它幾乎與afaik相同。 – Najzero

回答

3

也許「ID = 1」是表中的很早,所以當它讀取表順序,將打擊該行非常快,因爲你說「限價= 1」,它可以只在第一個結果後停止。

另外,有可能是涉及了一些緩存。

相關問題