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

Индексиране на външни ключове в Postgresql

tl;dr Трябва да добавите индекс към item_id . „Черната магия“ на индексирането на Postgres е разгледана в 11. Индекси .

Имате съставен индекс на (topic_id, item_id) и редът на колоните е важен. Postgres може да използва това за индексиране на заявки за topic_id , заявки към topic_id и item_id , но не (или по-малко ефективно) item_id сам.

От 11.3. Многоколонни индекси ...

-- indexed
select *
from topics_items
where topic_id = ?

-- also indexed
select *
from topics_items
where topic_id = ?
  and item_id = ?

-- probably not indexed
select *
from topics_items
where item_id = ?

Това е така, защото съставен индекс като (topic_id, item_id) първо съхранява идентификатора на темата, след това идентификаторите на елемент, които също имат този идентификатор на тема. За да търси ефективно идентификатор на елемент в този индекс, Postgres трябва първо да стесни търсенето с идентификатор на тема.

Postgres може обръща индекс, ако смята, че си струва усилието. Ако има малък брой възможни идентификатори на теми и голям брой възможни идентификатори на индекси, той ще търси идентификатора на индекса във всеки идентификатор на тема.

Да приемем например, че имате 10 възможни идентификатора на теми и 1000 възможни идентификатора на артикул и вашия индекс (topic_id, index_id) . Това е като да имате 10 ясно етикетирани кофи с ID на тема, всяка с 1000 ясно обозначени кофи с ID на елемент вътре. За да стигне до кофите с идентификатори на артикули, трябва да погледне във всяка кофа с идентификатор на тема. За да използвате този индекс при where item_id = 23 Postgres трябва да търси във всяка от 10-те кофи с ID на тема всички кофи с ID на елемент 23.

Но ако имате 1000 възможни идентификационни номера на теми и 10 възможни идентификационни номера на артикули, Postgres ще трябва да търси кофи с 1000 идентификационни номера на теми. Най-вероятно вместо това ще направи пълно сканиране на таблицата. В този случай бихте искали да обърнете индекса си и да го направите (item_id, topic_id) .

Това зависи до голяма степен от наличието на добра статистика на таблицата, което означава да се уверите, че автоматичното вакуумиране работи правилно.

Така че можете да се измъкнете с един индекс за две колони, ако една колона има много по-малко променливост от друга.

Postgres може също да използва множество индекси, ако смята, че ще накара заявката да се изпълни по-бързо . Например, ако сте имали индекс на topic_id и индекс на item_id , то може използвайте и двата индекса и комбинирайте резултатите. Например where topic_id = 23 or item_id = 42 може да използва индекса topic_id за търсене на тема ID 23 и индекса item_id за търсене на елемент ID 42, след което да комбинира резултатите.

Това обикновено е по-бавно от наличието на съставен (topic_id, item_id) индекс. Освен това може да бъде по-бавно от използването на единичен индекс, така че не се изненадвайте, ако Postgres реши да не използва множество индекси.

Като цяло, за b-дървовидни индекси, когато имате две колони, имате три възможни комбинации.

  • a + b
  • а
  • б

И имате нужда от два индекса.

  • (a, b) -- a и a + b
  • (b) – b

(a, b) обхваща и двете търсения за a и a + b. (b) корици, търсещи b .

Когато имате три колони, имате седем възможни комбинации.

  • a + b + c
  • a + b
  • a + c
  • а
  • b + c
  • б
  • c

Но имате нужда само от три индекса.

  • (a, b, c) -- a, a + b, a + b + c
  • (b, c) -- b, b + c
  • (c, a) -- c, c + a

Вероятно обаче всъщност искате да избегнете наличието на индекс в три колони. Често е по-бавно . Това, което всъщност искате, е това.

  • (a, b)
  • (b, c)
  • (c, a)

Четенето от индекс е по-бавно от четенето от таблицата. Искате вашите индекси да намалят броя на редовете, които трябва да бъдат прочетени, но не искате Postgres да трябва да сканира повече индекси от необходимото.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL Connection Pooling:Част 3 – Pgpool-II

  2. Функция за създаване на PostgreSQL

  3. Качване на изображения с помощта на Hibernate в PostgreSQL

  4. Postgres:Преобразуване на varchar в текст

  5. Използвайте тригери на наследени таблици, за да замените външни ключове