bảng My lead
có một chỉ số:Tại sao PostgreSQL (9.1) không sử dụng chỉ mục để chọn bình đẳng đơn giản?
\d lead
...
Indexes:
"lead_pkey" PRIMARY KEY, btree (id)
"lead_account__c" btree (account__c)
...
"lead_email" btree (email)
"lead_id_prefix" btree (id text_pattern_ops)
Tại sao không PG (9.1) sử dụng các chỉ số để lựa chọn bình đẳng đơn giản này? Email gần như tất cả các độc đáo ....
db=> explain select * from lead where email = 'blah';
QUERY PLAN
------------------------------------------------------------
Seq Scan on lead (cost=0.00..319599.38 rows=1 width=5108)
Filter: (email = 'blah'::text)
(2 rows)
khác chỉ số đánh thắc mắc dường như là OK (mặc dù tôi không biết tại sao người ta điều này không chỉ cần sử dụng chỉ số pkey):
db=> explain select * from lead where id = '';
QUERY PLAN
------------------------------------------------------------------------------
Index Scan using lead_id_prefix on lead (cost=0.00..8.57 rows=1 width=5108)
Index Cond: (id = ''::text)
(2 rows)
db=> explain select * from lead where account__c = '';
QUERY PLAN
----------------------------------------------------------------------------------
Index Scan using lead_account__c on lead (cost=0.00..201.05 rows=49 width=5108)
Index Cond: (account__c = ''::text)
(2 rows)
Lúc đầu, tôi nghĩ rằng nó có thể là do không đủ giá trị riêng biệt của email
. Ví dụ: nếu số liệu thống kê cho rằng email
là blah
đối với hầu hết bảng, thì quét seq sẽ nhanh hơn. Nhưng đó không phải là trường hợp:
db=> select count(*), count(distinct email) from lead;
count | count
--------+--------
749148 | 733416
(1 row)
Thậm chí nếu tôi buộc quét seq để được giảm, các nhà quy hoạch cư xử như thể nó không có lựa chọn nào khác:
db=> set enable_seqscan = off;
SET
db=> show enable_seqscan;
enable_seqscan
----------------
off
(1 row)
db=> explain select * from lead where email = '[email protected]';
QUERY PLAN
---------------------------------------------------------------------------
Seq Scan on lead (cost=10000000000.00..10000319599.38 rows=1 width=5108)
Filter: (email = '[email protected]'::text)
(2 rows)
Cũng cố gắng EXPLAIN ANALYZE
:
db=> explain analyze select * from lead where email = '[email protected]';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Seq Scan on lead (cost=10000000000.00..10000319732.76 rows=1 width=5102) (actual time=77845.244..77845.244 rows=0 loops=1)
Filter: (email = '[email protected]'::text)
Total runtime: 77857.215 ms
(3 rows)
Đây là đầu ra \d
(xin lỗi, phải che khuất tên cột và cắt để vừa với giới hạn của SO; xem phiên bản chưa được cắt tại http://pastebin.com/ve3gzJpY):
Table "lead"
Column | Type | Modifiers
--------------------------------------------+-----------------------------+-----------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | real |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | boolean |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
email | text |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | boolean |
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
account__c | text |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | text |
id | text | not null
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | real |
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | timestamp without time zone |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | real |
Indexes:
"lead_pkey" PRIMARY KEY, btree (id)
"lead_account__c" btree (account__c)
"lead_XXXXXXXXXXXXXXXXXXXXXX" btree (XXXXXXXXXXXXXXXXXXXXXX)
"lead_XXXXXXXXXXXXXXXXXXXXXX" btree (XXXXXXXXXXXXXXXXXXXXXX)
"lead_XXXXXXXXXXXXXXXXXXXXXX" btree (XXXXXXXXXXXXXXXXXXXXXX)
"lead_email" btree (email)
"lead_id_prefix" btree (id text_pattern_ops)
Đây là pg_dump --schema-only -t lead
(một lần nữa nhìn thấy uncropped tại http://pastebin.com/ve3gzJpY, với tên cột độc đáo cũng như trong trường hợp nó giúp tái lập):
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: lead; Type: TABLE; Schema: public; Owner: pod; Tablespace:
--
CREATE TABLE lead (
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX real,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX boolean,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX date,
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
account__c text,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX text,
id text NOT NULL,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX real,
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX timestamp without time zone,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX real
);
ALTER TABLE lead OWNER TO pod;
--
-- Name: lead_pkey; Type: CONSTRAINT; Schema: public; Owner: pod; Tablespace:
--
ALTER TABLE ONLY lead
ADD CONSTRAINT lead_pkey PRIMARY KEY (id);
--
-- Name: lead_account__c; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_account__c ON lead USING btree (account__c);
--
-- Name: lead_XXXXXXXXXXXXXXXXXXXX; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_XXXXXXXXXXXXXXXXXXXX ON lead USING btree (XXXXXXXXXXXXXXXXXXXX);
--
-- Name: lead_XXXXXXXXXXXXXXXXXXXX; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_XXXXXXXXXXXXXXXXXXXX ON lead USING btree (XXXXXXXXXXXXXXXXXXXX);
--
-- Name: lead_XXXXXXXXXXXXXXXXXXXX; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_XXXXXXXXXXXXXXXXXXXX ON lead USING btree (XXXXXXXXXXXXXXXXXXXX);
--
-- Name: lead_email; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_email ON lead USING btree (email);
--
-- Name: lead_id_prefix; Type: INDEX; Schema: public; Owner: pod; Tablespace:
--
CREATE INDEX lead_id_prefix ON lead USING btree (id text_pattern_ops);
--
-- PostgreSQL database dump complete
--
Một số catalogue PG bùa:
db=> select * from pg_index where indexrelid = 'lead_email'::regclass;
indexrelid | indrelid | indnatts | indisunique | indisprimary | indisexclusion | indimmediate | indisclustered | indisvalid | indcheckxmin | indisready | indkey | indcollation | indclass | indoption | indexprs | indpred
------------+-----------+----------+-------------+--------------+----------------+--------------+----------------+------------+--------------+------------+--------+--------------+----------+-----------+----------+---------
215251995 | 101034456 | 1 | f | f | f | t | f | t | t | t | 101 | 100 | 10043 | 0 | ¤ | ¤
(1 row)
Một số thông tin locale:
db=> show lc_collate;
lc_collate
-------------
en_US.UTF-8
(1 row)
db=> show lc_ctype;
lc_ctype
-------------
en_US.UTF-8
(1 row)
Tôi đã tìm kiếm trên một số câu hỏi SO trong quá khứ nhưng không có câu hỏi nào về truy vấn bình đẳng đơn giản như câu hỏi này.
Thật kỳ lạ ... bình đẳng đơn giản không cần chỉ mục 'text_pattern_ops', do đó khó giải thích. Bạn có thể tái tạo mẫu này trong một mẫu nhỏ không? Nếu vậy, hãy đăng lên sqlfiddle.com và liên kết tại đây. –
Vui lòng hiển thị định nghĩa bảng đầy đủ (tốt nhất là thông qua 'pg_dump'). –
@PeterEisentraut Cập nhật câu hỏi bằng lược đồ '\ d' và' pg_dump'. – Yang