PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Какъв е редът на записите в таблица със съставен първичен ключ

Този въпрос прави погрешното предположение, че първичният ключ изобщо налага ред на таблицата. Не е така. PostgreSQL таблиците нямат дефиниран ред, със или без първичен ключ; те са "купчина" от редове, подредени в блокове на страници. Подреждането се налага с помощта на ORDER BY клауза от заявки, когато желаете.

Може би си мислите, че PostgreSQL таблиците се съхраняват като индексно-ориентирани таблици, които се съхраняват на диска в ред на първичен ключ, но Pg не работи така. Мисля, че InnoDB съхранява таблици, организирани от първичния ключ (но не е проверено) и е по избор в бази данни на някои други доставчици, използвайки функция, често наричана "клъстерирани индекси" или "организирани от индекс таблици". Тази функция в момента не се поддържа от PostgreSQL (поне от 9.3).

Това каза, PRIMARY KEY се реализира с помощта на UNIQUE индекс и има подреждане на този индекс. Той се сортира във възходящ ред от лявата колона на индекса (и следователно първичния ключ) нататък, сякаш е ORDER BY col1 ASC, col2 ASC, col3 ASC; . Същото важи и за всяко друго b-дърво (за разлика от GiST или GIN) индекс в PostgreSQL, тъй като те са имплементирани с помощта на b+дървета.

Така че в таблицата:

CREATE TABLE demo (
   a integer,
   b text, 
   PRIMARY KEY(a,b)
);

системата автоматично ще създаде еквивалента на:

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

Това ви се съобщава, когато създавате таблица, напр.:

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

Можете да видите този индекс, когато разглеждате таблицата:

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)

Можете да CLUSTER на този индекс, за да пренаредите таблицата според първичния ключ, но това е еднократна операция. Системата няма да поддържа това подреждане - въпреки че ако има свободно място на страниците поради непонятно FILLFACTOR Мисля, че ще се опита.

Едно следствие от присъщото подреждане на индекса (но не и на купчината) е, че той е много по-бързо за търсене на:

SELECT * FROM demo ORDER BY a, b;
SELECT * FROM demo ORDER BY a;

отколкото:

SELECT * FROM demo ORDER BY a DESC, b;

и нито един от тях изобщо не може да използва индекса на първичния ключ, те ще направят seqscan, освен ако нямате индекс на b :

SELECT * FROM demo ORDER BY b, a;
SELECT * FROM demo ORDER BY b;

Това е така, защото PostgreSQL може да използва индекс на (a,b) почти толкова бързо, колкото индекс на (a) сам. Не може да използва индекс на (a,b) сякаш е индекс на (b) сам - дори не бавно, просто не може.

Що се отнася до DESC запис, за този Pg трябва да извърши обратно индексно сканиране, което е по-бавно от обикновеното сканиране на индекса напред. Ако виждате много обратни индексни сканирания в EXPLAIN ANALYZE и можете да си позволите разходите за производителност на допълнителния индекс, можете да създадете индекс в полето в DESC поръчка.

Това е вярно за WHERE клаузи, а не само ORDER BY . Можете да използвате индекс на (a,b) за търсене на WHERE a = 4 или WHERE a = 4 AND b = 3 но не за търсене на WHERE b = 3 сам.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Оптимизиране на груповата максимална заявка

  2. Как да разбера кой дял ще се използва при разделяне на хеш на Postgres?

  3. Как Atand() работи в PostgreSQL

  4. Нормализиране на Unicode в PostgreSQL 13

  5. Как Atanh() работи в PostgreSQL