PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Thứ tự các bản ghi trong bảng có khóa chính tổng hợp là gì

Câu hỏi này tạo ra giả định sai lầm rằng khóa chính áp đặt một thứ tự bảng nào cả. 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 trong các khối trang. Đặt hàng được áp dụng bằng cách sử dụng ORDER BY mệnh đề 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 hướ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 Pg hoạt động. Tôi nghĩ rằng InnoDB lưu trữ các bảng được tổ chức theo khóa chính (nhưng chưa được kiểm tra) và nó là tùy chọn trong cơ sở dữ liệu của một số nhà cung cấp khác bằng cách sử dụng một tính năng thường được gọi là "chỉ mục nhóm" hoặc "bảng được tổ chức theo chỉ mục". Tính năng này hiện không được PostgreSQL hỗ trợ (ít nhất là 9.3).

Điều đó nói lên rằng, PRIMARY KEY được triển khai bằng UNIQUE chỉ mục, và có một 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 với GiST hoặc GIN) trong PostgreSQL, vì chúng được triển khai bằng cách sử dụng b + tree.

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 tương đương với:

CREATE UNIQUE INDEX demo_pkey ON demo(a ASC, b ASC);

Điều 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ể thấy 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à hoạt động một lần. Hệ thống sẽ không duy trì thứ tự đó - mặc dù nếu có dung lượng trống trong các trang do FILLFACTOR không mặc định Tôi nghĩ nó sẽ cố gắng.

Một hệ quả của thứ tự vốn có của chỉ mục (nhưng không phải là đống) là nó 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à cả hai thứ này đều không thể sử dụng chỉ mục khóa chính, chúng sẽ quét 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 một chỉ mục trên (a,b) nhanh như một chỉ mục trên (a) một mình. Nó không thể sử dụng chỉ mục trên (a,b) như thể nó là một chỉ mục trên (b) một mình - thậm chí không từ từ, nó chỉ là không thể.

Đối với DESC mục nhập, đối với Pg đó phải thực hiện quét chỉ mục ngược, tốc độ này 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 nhiều lần quét chỉ mục ngược trong EXPLAIN ANALYZE và bạn có thể chi trả 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 trong DESC đặt hàng.

Điều này đúng với WHERE các mệnh đề, 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 để tìm kiếm WHERE b = 3 một mình.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để đặt lại mật khẩu người dùng mặc định postgresql 9.2 (thường là 'postgres') trên mac os x 10.8.2?

  2. Thêm một cột làm khóa ngoại thì cột LỖI được tham chiếu trong ràng buộc khóa ngoại không tồn tại

  3. không thể tạo khóa chính tự động tăng thêm bằng flask-sqlalchemy

  4. ClusterControl - Quản lý sao lưu nâng cao - PostgreSQL

  5. Làm cách nào để chuyển ứng dụng ray hiện có của tôi lên heroku? (sqlite đến postgres)