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