Câu hỏi này làm cho giả định sai lầm rằng khóa chính áp đặt một thứ tự bảng. Nó không. Các bảng PostgreSQL không có thứ tự xác định, có hoặc không có khóa chính; chúng là một "đống" các hàng được sắp xếp theo các khối trang. Việc đặt hàng được áp dụng theo mệnh đề ORDER BY
của các truy vấn khi muốn.
Bạn có thể nghĩ rằng các bảng PostgreSQL được lưu trữ dưới dạng bảng chỉ mục được lưu trữ trên đĩa theo thứ tự khóa chính, nhưng đó không phải là cách thức hoạt động của Pg. Tôi nghĩ rằng InnoDB lưu trữ các bảng được tổ chức bởi khóa chính (nhưng chưa được kiểm tra), và nó tùy chọn trong một số cơ sở dữ liệu của các nhà cung cấp khác sử dụng tính năng thường được gọi là "chỉ mục nhóm" hoặc "bảng được chỉ mục". Tính năng này hiện không được hỗ trợ bởi PostgreSQL (ít nhất là 9.3).
Điều đó nói rằng, PRIMARY KEY
được triển khai bằng cách sử dụng chỉ mục UNIQUE
và có thứ tự cho chỉ mục đó. Nó được sắp xếp theo thứ tự tăng dần từ cột bên trái của chỉ mục (và do đó là khóa chính) trở đi, như thể nó là ORDER BY col1 ASC, col2 ASC, col3 ASC;
. Điều này cũng đúng với bất kỳ chỉ mục b-tree nào khác (khác biệt với GiST hoặc GIN) trong PostgreSQL, vì chúng được thực hiện bằng cách sử dụng b+trees.
Vì vậy, trong bảng:
CREATE TABLE demo (
a integer,
b text,
PRIMARY KEY(a,b)
);
hệ thống sẽ tự động tạo ra tương đương với:
CREATE UNIQUE INDEX demo_pkey ON demo(a ASC, b ASC);
này được báo cáo cho bạn khi bạn tạo một bảng, ví dụ:
regress=> CREATE TABLE demo (
regress(> a integer,
regress(> b text,
regress(> PRIMARY KEY(a,b)
regress(> );
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "demo_pkey" for table "demo"
CREATE TABLE
Bạn có thể xem chỉ mục này khi kiểm tra bảng:
regress=> \d demo
Table "public.demo"
Column | Type | Modifiers
--------+---------+-----------
a | integer | not null
b | text | not null
Indexes:
"demo_pkey" PRIMARY KEY, btree (a, b)
Bạn có thể CLUSTER
trên chỉ mục này để sắp xếp lại bảng theo khóa chính, nhưng đó là thao tác một lần. Hệ thống sẽ không duy trì thứ tự đó - mặc dù nếu có không gian trống trong các trang do không mặc định FILLFACTOR
Tôi nghĩ rằng nó sẽ cố gắng.
Một hệ quả của trật tự vốn có của chỉ số (nhưng không phải là đống) là nó là nhiều nhanh hơn để tìm kiếm:
SELECT * FROM demo ORDER BY a, b;
SELECT * FROM demo ORDER BY a;
hơn:
SELECT * FROM demo ORDER BY a DESC, b;
và không ai trong số tất cả những chỉ số này có thể sử dụng chỉ mục khóa chính, chúng sẽ thực hiện seqscan trừ khi bạn có chỉ mục trên b
:
SELECT * FROM demo ORDER BY b, a;
SELECT * FROM demo ORDER BY b;
Điều này là do PostgreSQL có thể sử dụng chỉ mục trên (a,b)
gần như nhanh như chỉ mục trên (a)
một mình.Nó không thể sử dụng một chỉ số trên (a,b)
như thể nó là một chỉ số trên (b)
một mình - thậm chí không chậm, nó chỉ có thể không.
Đối với mục nhập DESC
, cho rằng một Pg phải thực hiện quét chỉ mục đảo ngược, chậm hơn so với quét chỉ mục chuyển tiếp thông thường. Nếu bạn thấy rất nhiều lần quét chỉ mục đảo ngược trong EXPLAIN ANALYZE
và bạn có thể đủ khả năng chi phí hiệu suất của chỉ mục bổ sung, bạn có thể tạo chỉ mục trên trường theo thứ tự DESC
.
Điều này đúng với các điều khoản WHERE
, không chỉ ORDER BY
. Bạn có thể sử dụng chỉ mục trên (a,b)
để tìm kiếm WHERE a = 4
hoặc WHERE a = 4 AND b = 3
nhưng không phải để tìm kiếm WHERE b = 3
một mình.
Vì vậy, tôi nên giả định rằng tra cứu trên cơ sở cột ngoài cùng bên trái sẽ là nhanh nhất so với cột bên phải (các cột tôi đang nói về là tất cả các cột tạo thành khóa chính)? –
@AbhishekChính xác; sử dụng cột ngoài cùng bên trái của PK (hoặc tra cứu sử dụng cả hai cột) sẽ sử dụng chỉ mục, trong khi sử dụng cột ngoài cùng bên phải của chỉ * PK * sẽ không thể sử dụng chỉ mục nào cả. Có thể hữu ích khi tạo chỉ mục thứ hai trên cột ngoài cùng bên phải nếu bạn cần tra cứu rất nhiều, hoặc đảo ngược thứ tự của khóa chính nếu bạn không cần phải xem cột khác một mình. –
@AbhishekJain Bạn được chào đón. Tôi khuyên bạn nên làm quen với lệnh 'EXPLAIN ANALYZE' và với lệnh' psql' shell. Cả hai sẽ giúp bạn hiểu cách PostgreSQL hoạt động tốt hơn nhiều, phân tích cách truy vấn được thực hiện, kiểm tra các chiến lược lập chỉ mục khác nhau, v.v. http://explain.depesz.com/ có thể hữu ích khi cố gắng hiểu các kế hoạch truy vấn lớn và phức tạp. –