PostgreSQL: промышленная разработка баз данных Лекция 6 Традиционные индексы: B-tree, hash, R-tree. Обобщённые индексы: GiST, GIN. Специальные типы данных с поддержкой GiST и GIN. Полнотекстовый поиск. Геометрические типы данных.
PostgreSQL: промышленнаяразработка баз данных
Лекция 6
Традиционные индексы: Btree, hash, Rtree. Обобщённые индексы: GiST, GIN. Специальные типы данных с поддержкой GiST и GIN. Полнотекстовый поиск. Геометрические типы данных.
PostgreSQL: промышленная разработка баз данных. Лекция 6
Индексы в PostgreSQL
● Btree● Hash● Rtree● GiST (обобщенное поисковое дерево)● GIN (обратный индекс)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Индексы в PostgreSQL
Btree Hash Rtree – теперь тоже GiST GiST (обобщенное поисковое дерево) GIN (обратный индекс)
Фёдор Сигаев, Олег Бартунов
PostgreSQL: промышленная разработка баз данных. Лекция 6
Cоздание индекса
test=# \h CREATE INDEXCommand: CREATE INDEXDescription: define a new indexSyntax:CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ] ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ) [ WITH ( storage_parameter = value [, ... ] ) ] [ TABLESPACE tablespace ] [ WHERE predicate ]
CREATE INDEX i_table1_name1 ON table1 (column1);
CREATE INDEX i_table1_name1 ON table1 USING btree (column1);
PostgreSQL: промышленная разработка баз данных. Лекция 6
Общие возможности использования индексов в PostgreSQL
Частичные индексы
CREATE INDEX ... WHERE ... Функциональные индексы
CREATE INDEX ... USING btree(myfunc(a))
C
− уникальные функциональные индексы− индексирование данных “экзотических” типов (XML, array, ...)
Многоколоночные индексы
− следим за правильным порядком столбцов− избегаем ненужных одноколоночных индексов
GiSTиндексы для полнотекстового поиска, для спец. типов данных
GINиндексы для массивов, полнотекстового поиска и т.д.
CLUSTER table USING indexname
PostgreSQL: промышленная разработка баз данных. Лекция 6
Общие возможности использования индексов в PostgreSQL
● CREATE INDEX CONCURRENTLY ...
● CREATE INDEX ... WITH (fillfactor = ...)
● Необходимость в перестроении индексов (read/fetch ratio):
select indexrelname, idx_tup_read, idx_tup_fetch, case when idx_tup_fetch = 0 then 100 else idx_tup_read / idx_tup_fetch end as ratio from pg_stat_user_indexes order by ratio desc;
PostgreSQL: промышленная разработка баз данных. Лекция 6
Оптимизация: общие рекомендации
Сбор статистики, мониторинг, анализ логов (pgFouine)
Итерационное выявление медленных запросов
Иногда лучше перестроить запрос, а не создать N новых индексов
Следить за кардинальностью и селективностью промежуточных результатов (SELECT * FROM a, b)
Потенциальные источники проблем: LEFT JOIN, count(), UNION вместо UNION ALL, DISTINCT, WHERE ... IN (...), соединение 100 таблиц, неожиданное «выпрямление» запросов с подзапросами, «вязанка» индексов вместо одногодвух
Не забывать об ANALYZE после массивных изменений!
PostgreSQL: промышленная разработка баз данных. Лекция 6
Оптимизация: общие рекомендации
При решении проблемы убедитесь в том, что вам не нужны VACUUM & ANALYZE
Запускайте EXPLAIN ANALYZE не менее двух раз (не забываем про кэш)
Читайте план снизу вверх, ищите, где начинаются замедления и/или ошибки планировщика
При возможности, используйте реальные данные в тестировании (Slony?) и оборудование, приближенное к production
Обращайтесь за помощью: pgsqlperformance, IRC, sql.ru, коммерческая поддержка
PostgreSQL: промышленная разработка баз данных. Лекция 6
B+деревья
Позволяет осуществлять быстрый поиск по запросам интервального типа (операции <, <=, =, >=, >)
Сильноветвящееся
Сбалансированное
Гарантированное время поиска
Используется:
файловые системы (NTFS, ReiserFS, XFS)
СУБД (практически все)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Rдеревья
Для быстрого поиска объектов на плоскости (операции @>, <@)
Струкрутра аналогична B+деревьям
В ядре PostgreSQL реализация теперь на основе GiST!
PostgreSQL: промышленная разработка баз данных. Лекция 6
GiST – обобщённое поисковое дерево
Позволяет реализовывать индексную поддержку для различных типов данных
Структура индекса – деревья, аналогичные B+деревьям; GiST не знает, с какими именно данными и с какими операциями имеем дело
Для создания своего индекса необходимо реализовать 7 интерфейсных функций (см. http://www.citforum.ru/database/postgres/gist/)
Реализации:
B+деревья Rдеревья RDдеревья (для типов данных вида «множество»)
полнотекстовый поиск (типы данных tsvector, tsquery) contrib/hstore contrib/ltree целочисленные массивы
PostgreSQL: промышленная разработка баз данных. Лекция 6
GIN – обобщённый обратный индекс
Позволяет реализовывать “обратный” индекс для различных типов данных
Для создания своего индекса необходимо реализовать 4 интерфейсных функции
Вставка намного медленнее, чем у GiST, поиск быстрее, возможности масштабирования намного лучше (большие объёмы данных)
Реализации:
полнотекстовый поиск contrib/hstore массивы (любые!)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Полнотекстовый поиск Как организовать поиск по тексту?
mirtesen=# EXPLAIN ANALYZE SELECT * FROM person WHERE person_description ILIKE '% %'программист ; QUERY PLAN Seq Scan on person (cost=0.00..10212.05 rows=1 width=532) (actual time=4.581..240.464 rows=315 loops=1) Filter: (person_description ~~* '% %'::text)программист Total runtime: 240.792 ms(3 rows)
– Нет индексной поддержки! (есть для запросов вида LIKE 'blabla%' со многими оговорками)
Специальные типы данных (tsquery, tsvector) и специальный индекс (основанный на GiST или GIN, «по вкусу»):
mirtesen=# EXPLAIN ANALYZE SELECT * FROM person WHERE obj_tsvector @@ to_tsquery('utf8_russian', ' ')программисты ; QUERY PLAN Bitmap Heap Scan on person (cost=9.08..378.64 rows=100 width=532) (actual time=9.065..12.294 rows=316 loops=1) Filter: (obj_tsvector @@ ''' '''::tsquery)программист > Bitmap Index Scan on i_person__tsvector (cost=0.00..9.05 rows=100 width=0) (actual time=8.767..8.767 rows=346 loops=1) Index Cond: (obj_tsvector @@ ''' '''::tsquery)программист Total runtime: 12.563 ms(5 rows)
tsvector
tsquery
PostgreSQL: промышленная разработка баз данных. Лекция 6
Полнотекстовый поиск
До PostgreSQL 8.3: contrib/tsearch2
Начиная с 8.3: встроен в ядро, появился SQLподобный синтаксис (не UPDATE TABLE pg_ts_dict..., a ALTER TEXT SEARCH DICTIONARY)
Обладает широкими возможностями:
− Морфология (можно использовать OpenOfficeсловари)
− Стемминг
− Словари синонимов
− Тезаурус
− Ранжирование на основе релевантности (быстрая сортировка)
− “Подсветка” найденных фрагментов
− [скоро!] Префиксный поиск
− Отличная работа с русским языком // ещё бы ;)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Полнотекстовый поиск
До PostgreSQL 8.3: contrib/tsearch2
Начиная с 8.3: встроен в ядро, появился SQLподобный синтаксис (не UPDATE TABLE pg_ts_dict..., a ALTER TEXT SEARCH DICTIONARY)
Обладает широкими возможностями:
− Морфология (можно использовать OpenOfficeсловари)
− Стемминг
− Словари синонимов
− Тезаурус
− Ранжирование на основе релевантности (быстрая сортировка)
− “Подсветка” найденных фрагментов
− [скоро!] Префиксный поиск
− Отличная работа с русским языком // ещё бы ;)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Геометрические типы данных
Типы, «идущие в поставке» (работа на плоскости!): point, box, lseg, line, path, polygon и circle
Есть набор функций и операторов
Индексная поддержка — Rдеревья (GiST!):mirtesen=# EXPLAIN ANALYZE SELECT COUNT(1) FROM person2geo WHERE o2g_point <@ box(point(44.590467181309, 43.1982421875), point(53.85252660045, 69.2578125)) and obj_status_did = 1; QUERY PLAN Aggregate (cost=7421.02..7421.03 rows=1 width=0) (actual time=59.503..59.503 rows=1 loops=1) > Bitmap Heap Scan on person2geo (cost=1501.17..7353.57 rows=26980 width=0) (actual time=16.449..58.461 rows=1525 loops=1) Recheck Cond: (obj_status_did = 1) Filter: (o2g_point <@ '(53.85252660045,69.2578125),(44.590467181309,43.1982421875)'::box) > Bitmap Index Scan on i_person2geo__obj_obj_id (cost=0.00..1494.42 rows=53960 width=0) (actual time=15.487..15.487 rows=54129 loops=1) Total runtime: 59.597 ms(6 rows)
PostgreSQL: промышленная разработка баз данных. Лекция 6
Геометрические типы данных
Если возможностей не хватает:
PostGIS (http://postgis.refractions.net/) — дополнительный проект, возможности для GIS (сферические координаты; поддержка стандарт OpenGIS; GiST для индексной поддержки)
pgSphere — доп. модуль для работы с данными на сфере, использует GiST
Q3C — доп. модуль для работы с данными на сфере, «быстрое» отображение в одномерное пространство, используется btree
Q3C segmentation
«Социальная сеть на карте» MirTesen.ru
PostgreSQL: промышленная разработка баз данных. Лекция 6
Литература: рекомендации для данной лекции
● PostgreSQL Reference Manual
● 11. Indexes● 14. Performance Tips● 43.5. Planner/Optimizer● 55. How the Planner Uses Statistics
● Бартунов О., Сигаев Ф. Написание расширений для PostgreSQL с использованием GiST http://www.citforum.ru/database/postgres/gist/
● Дейт, К.. Введение в системы баз данных — Глава 17.
● Кузнецов, С. Д. Основы современных баз данных — 9.2. Индексы http://citforum.ru/database/osbd/glava_39.shtml#_4_1_2
● ГарсиаМолина, Г., Ульман, Дж., Уидом, Дж. Системы баз данных. Полный курс. — Главы 1316
PostgreSQL: промышленная разработка баз данных. Лекция 6
Контакты
● Blog: http://nikolay.samokhvalov.com
● XMPP/GTalk: [email protected]
● Skype: samokhvalov & postgresmen
● +7 905 783 9804