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

PostgreSQL:Защо тази заявка не използва моя индекс?

Както вече разбрахте, проблемът е свързан с използването на оператори, различни от равни. Индексът може да се използва най-ефективно само за най-левите колони, които се сравняват с равни (плюс едно условие за диапазон).

Във вашия пример:

create index i on t (a,b,c,d);
where a=1 and b=11 and c!=5 and d<8;

Може да използва индекса само за a и b ефективно. Това означава, че DB извлича всички редове, съответстващи на a и b условие и след това проверява всеки ред спрямо останалите условия.

Когато промените филтъра на c на равно, извлича (потенциално) по-малко редове (само тези, които съответстват на a и b и c ) и след това проверява тези (по-малко) редове спрямо d филтър. Използването на индекса е по-ефективно в този случай.

Като цяло, програмата за планиране на заявки на PostgreSQL оценява и двете опции:(1) използвайки индекса; (2) извършване на SeqScan. И за двете изчислява разходна стойност — колкото по-висока е тя, толкова по-лоша е очакваната производителност. Следователно, той взема този с по-малка себестойност. Ето как решава дали да използва индекса или не, няма фиксиран праг.

И накрая, по-горе е написано "плюс едно условие за диапазон". Това означава, че може не само да използва индекса по най-ефективния начин, ако използвате знаци за равенство, но и за едно единствено условие за диапазон.

Като се има предвид, че имате едно единствено условие за диапазон в заявката си, предлагам да промените индекса по следния начин:

create index i on t (a,b,d,c);

Сега може да използва филтрите на a и b и d ефективно с индекса и трябва само да филтрира редовете, където c!=5 . Въпреки че този индекс може да се използва по-ефективно за вашата заявка като оригиналния, това не означава автоматично, че PG ще го използва. Зависи от разчетите за разходите. Но опитайте.

И накрая, ако това не е достатъчно бързо и стойността 5 използвате в израза c!=5 е константа, можете да помислите за частичен индекс:

 create index i on t (a,b,d)
        where c!=5;

Можете да направите това и с всички други колони, ако стойностите, с които ги сравнявате, са константи.

Препратки:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да импортирам JSON файл в PostgreSQL?

  2. Как мога да постигна същото поведение на сортиране на Postgres в Linux като това в Mac OS?

  3. Какви са предимствата от използването на обединяване на транзакции с pgbouncer?

  4. Предизвикателство за рекурсивна заявка - прост пример за родител/дете

  5. Въведете час с часова зона лятно часово време