LINUX.ORG.RU

Индекс для сортировки

 ,


0

1

СУБД PostgreSQL, таблица Документы первичный ключ Документ, поле Код типа text. Есть запрос

SELECT s.*
FROM "Документы" s
where "Документ" = ANY(ARRAY[807830, 807831, 807832, 807833, 807834, 807835, 807836, 807837, 807838, 807839
])
ORDER BY
s."Код"

Создал индекс

CREATE INDEX "index_sort"
	ON "Документы" USING btree
	("Документ" NULLS LAST, "Код" text_pattern_ops NULLS LAST);

Но почему-то планировщик его не использует, делал VACUUM, REINDEX, используется индекс по первичному ключу, план такой:

"Sort  (cost=48.74..48.77 rows=10 width=174) (actual time=0.061..0.062 rows=10 loops=1)"
"  Sort Key: "Код"
"  Sort Method: quicksort  Memory: 26kB"
"  Buffers: shared hit=31"
"  ->  Index Scan using "pДокумент" on "Документы" s  (cost=0.42..48.58 rows=10 width=174) (actual time=0.013..0.025 rows=10 loops=1)"
"        Index Cond: ("Документ" = ANY ('{807830,807831,807832,807833,807834,807835,807836,807837,807838,807839}'::integer[]))"
"        Buffers: shared hit=31"
"Planning time: 0.168 ms"
"Execution time: 0.077 ms"

Как заставить планировщик использовать индекс?

Зачем ему твой индекс использовать, когда он использует индекс по первичному ключу, который самый быстрый? Не говоря уже о том, что у тебя там в индексе поле Код, которое для фильтрации не нужно, поэтому твой индекс вообще безполезен.

pi11 ★★★★★
()
Последнее исправление: pi11 (всего исправлений: 2)
Ответ на: комментарий от pi11

Почему индекс бесполезен? Индексы также могут применяться для сортировки, поле Код используется при сортировке

Хочется использовать в запросе составной индекс, чтобы в плане был IndexOnlyScan index_sort или IndexScan index_sort

Подумал, что планировщику для 10 записей легче просканировать все 10 записей для сортировки, чем использовать индекс.

Пробовал в запросе искать по массиву из 10000 идентификаторов,
но планировщик не стал использовать новый иендекс

polin11
() автор топика
Ответ на: комментарий от polin11

А можешь показать explain для запроса с 10к идентификаторами, только добавь еще limit 10 в запрос.

pi11 ★★★★★
()

Перефразирую вопрос:

Есть таблица ФИО(фамилия, имя, отчество)

Есть индекс1 (фамилия)
Есть индекс2 (фамилия, имя)

Запрос: дай фио, где фамилия in (????) и order by имя

Логично, что более оптимально делать скан по фамилиям,а потом результат сортировать по имени. Т.к. как нет смысла сортировать по имени, а потом перебирать весь список в поисках нужных фамилий.

Технически, же, эти 2 индекса, с точка зрения постргреса эквиваленты, только индекс 2 по размерам больше.

И даже индекс (Код,Документ) не заставит постгрес отказаться от индекса начинающегося с (документ), т.к. это просто дешевле

Планировщику совершенно очевидно что если M>N, то намного проще прочитать N строк, и их отсортировать, чем прочитать все M строк, и из них выбрать N подходящих

anonymous
()
Ответ на: комментарий от polin11

Индексы также могут применяться для сортировки

Могут, но в данном случае у тебя упорядочивание по «документ,код» что годится для сортировки по документу и для сортировки по кодам для одного и того же документа. Для сортировки просто по коду это не подходит.

PS: если тебе действительно не нужно выбирать 100500 документов, то пусть сортирует без индекса. Вероятно это будет даже быстрее.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

PS: если тебе действительно не нужно выбирать 100500 документов, то пусть сортирует без индекса. Вероятно это будет даже быстрее.

Запрос из ОП вообще всегда возвращает максимум 10 документов, потому что в where стоит условие по первичному ключу таблицы. Ясен пень, что тут для эффективной сортировки максимум 10 записей индекс по коду не нужен.

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

Запрос из ОП

Просто пример и ничего не говорит о том, сколько документов запрашивается в реальных условиях.

no-such-file ★★★★★
()

Всё перед глазами. Он сначала выбирает (SELECT … WHERE), а потом сортирует (ORDER BY). Причём сортирует не таблицу с твоим индексом, а анонимный результат из предыдущего этапа, который вообще без индексов.

anonymous
()
Ответ на: комментарий от polin11

10k записей тоже немного. Не факт что дешевле использовать индекс, а потом чтение записей с диска, когда вся таблица в память может уместиться.

kardapoltsev ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.