Я прочитал о функциональных индексах и индексах только в документах/вики, опубликованных Postgres.postgres 9.6 индекс только сканирование по функциональному индексу логически возможно, но не выполнено
теперь у меня есть запрос типа:
SELECT(xpath('/document/uuid/text()', xmldata))[1]::text,
(xpath('/document/title/text()', xmldata))[1]::text
FROM xmltable
WHERE(xpath('/document/uuid/text()', xmldata))[1]::text = 'some-uuid-xxxx-xxxx'
и индекс:
CREATE INDEX idx_covering_index on xmltable using btree (
((xpath('/document/uuid/text()', xmldata))[1]::text),
((xpath('/document/title/text()', xmldata))[1]::text)
)
Этот индекс, глядя на него логически, индекс покрытия и должен позволить индексному-только сканирование , так как все запрошенные значения содержатся в индексе (uuid и title)
Теперь я знаю, что Postgres распознает только индексы покрытия на функциональных индексах, если столбцы, используемые в функции-cal Ls также содержатся
например .:
SELECT to_upper(column1) from table where id >10
1) не могут быть покрыты по этому показателю:
CREATE INDEX idx_covering_index on xmltable using btree (id, to_upper(column1));
2), но может быть покрыта этой одной:
CREATE INDEX idx_covering_index on xmltable using btree (column1, id, to_upper(column1));
, что приводит к индексированию только сканирования.
Если теперь я стараюсь это с моей настройкой XML:
CREATE INDEX idx_covering_index on xmltable using btree (xmldata,
((xpath('/document/uuid/text()', xmldata))[1]::text),
((xpath('/document/title/text()', xmldata))[1]::text)
)
Я получаю сообщение об ошибке:
data type xml has no default operator class for access method "btree"
справедливой достаточно, к сожалению, как правило, используется "text_ops"
или "text_pattern_ops"
не принимает "XML", как input - таким образом, мой индекс - хотя он будет охватывать все значения - не может поддерживать индексирование только.
Можно ли это обработать таким образом, чтобы обеспечить возможность сканирования только по индексу?
@ EDIT1:
Я знаю, что Postgres не может использовать индекс видел в 1) в качестве покрытия индекса, но может использовать индекс, как 2)
Я также попытался с помощью очень простых таблиц для проверки этого поведения , и я тоже помню, что прочитал это, но я не могу за всю жизнь помнить, где.
create table test (
id serial primary key,
quote text
)
insert into test (number, quote) values ('I do not know any clever quotes');
insert into test (number, quote) values ('I am sorry');
CREATE INDEX idx_test_functional on test using btree ((regexp_replace(quote, '^I ', 'BillDoor ')));
set enable_seqscan = off;
analyze test;
explain select quote from test where regexp_replace(quote, '^I ', 'BillDoor ') = 'BillDoor do not know any clever quotes'
--> "Index Scan using idx_test_functional on test (cost=0.13..8.15 rows=1 width=27)"
drop index idx_test_functional;
CREATE INDEX idx_test_functional on test using btree (quote, (regexp_replace(quote, '^I ', 'BillDoor ')));
analyze test;
explain select quote from test where regexp_replace(quote, '^I ', 'BillDoor ') = 'BillDoor do not know any clever quotes'
--> "Index Only Scan using idx_test_functional on test (cost=0.13..12.17 rows=1 width=27)"
@ EDIT2:
Полное определение таблице XMLTABLE:
id serial primary key (clustered),
xmldata xml (only data used to filter queries)
history xml (never queried or read, just kept in case of legal inquiry)
fileinfo text (seldom quieried, sometimes retrieved)
"timestamp" timestamp (mainly for legal inquiries too)
В таблице приведены около .: 500.000 записей, размер xmldata составляет от 350 до 800 байт, история намного больше, но редко извлекается и никогда не используется в фильтрах.
Для записи, чтобы получить реальные результаты, я всегда побежал analyze xmltable
после того, как создал или сбросил индекс
полный план выполнения для запроса:
explain analyze select (xpath('/document/uuid/text()', d.xmldata))[1]::text as uuid
from xmltable as d
where
(xpath('/document/uuid/text()', d.xmldata))[1]::text = 'some-uuid-xxxx-xxxx' and (xpath('/document/genre/text()', d.xmldata))[1]::text = 'bio'
охватываемого этого indizies:
create index idx_genre on xmltable using btree (((xpath('/document/genre/text()', xmldata))[1]::text));
create index idx_uuid on xmltable using btree (((xpath('/document/uuid/text()', xmldata))[1]::text));
create index idx_uuid_genre on xmltable using btree (((xpath('/document/uuid/text()', xmldata))[1]::text), ((xpath('/document/genre/text()', xmldata))[1]::text));
приводит сначала чтобы:
"Index Scan using idx_genre on xmldata d (cost=0.42..6303.05 rows=18154 width=32)"
" Index Cond: (((xpath('/document/genre/text()'::text, xmldata, '{}'::text[]))[1])::text = 'bio'::text)"
" Filter: (((xpath('/document/uuid/text()'::text, xmldata, '{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text)"
достаточно справедливо я думал, только для тестирования я заставлю его использовать - в моем сознании - индекс покрытия:
drop index idx_uuid;
drop index idx_genre;
и теперь я получаю:
"Bitmap Heap Scan on xmltable d (cost=551.13..16025.51 rows=18216 width=32)"
" Recheck Cond: ((((xpath('/document/genre/text()'::text, xmldata, '{}'::text[]))[1])::text = 'bio'::text) AND (((xpath('/document/uuid/text()'::text, xmldata, '{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text))"
" -> Bitmap Index Scan on idx_uuid_genre (cost=0.00..546.58 rows=18216 width=0)"
" Index Cond: ((((xpath('/document/genre/text()'::text, xmldata, '{}'::text[]))[1])::text = 'bio'::text) AND (((xpath('/document/uuid/text()'::text, xmldata, '{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text))"
Я также попытался переключить позиции uuid и жанра в индекс, тот же план выполнения.
«Теперь я знаю, что postgres распознает только маскировки инклюзив на функциональных функциях, если также используются столбцы, в которые встроены функции-вызовы», можете ли вы предоставить любую ссылку на документацию, подтверждающую это; это очень противоречиво. Это ... как вы «теперь знаете». –
Каково полное определение таблицы 'xmltable'? Каков план выполнения для оператора, если индекс присутствует? Использует ли Postgres индекс для поиска индекса или вообще не использует этот индекс? –
Я знаю, потому что я пробовал с и без xml, обычных таблиц, json и т. Д. Мне также показалось странным - я отредактирую вопрос, чтобы добавить это – billdoor