Вы находитесь на странице: 1из 19

PostgreSQL: промышленная

разработка баз данных
Лекция 6

Традиционные индексы: B­tree, hash, R­tree. 
Обобщённые индексы: GiST, GIN. 
Специальные типы данных с поддержкой GiST и GIN. 
Полнотекстовый поиск. Геометрические типы данных.
Индексы в PostgreSQL

● B­tree
● Hash
● R­tree
● GiST (обобщенное поисковое дерево)
● GIN (обратный индекс)

PostgreSQL: промышленная разработка баз данных. Лекция 6
Индексы в PostgreSQL

 B­tree
 Hash
 R­tree – теперь тоже GiST
 GiST (обобщенное поисковое дерево)
 GIN (обратный индекс)
Фёдор Сигаев, Олег Бартунов

PostgreSQL: промышленная разработка баз данных. Лекция 6
Cоздание индекса
test=# \h CREATE INDEX
Command:     CREATE INDEX
Description: define a new index
Syntax:
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))
− уникальные функциональные индексы
− индексирование данных “экзотических” типов (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
 Обращайтесь за помощью: pgsql­performance, 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) и специальный индекс  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 
tsquery 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)

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 для индексной 
поддержки) «Социальная сеть на карте» MirTesen.ru
 pgSphere — доп. модуль для работы с 
данными на сфере, использует GiST
 Q3C — доп. модуль для работы с 
данными на сфере, «быстрое» 
отображение в одномерное 
пространство, используется btree

Q3C segmentation
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 
● Гарсиа­Молина, Г., Ульман, Дж., Уидом, Дж. Системы баз данных. Полный 
курс. — Главы 13­16

PostgreSQL: промышленная разработка баз данных. Лекция 6
Контакты
● nikolay@samokhvalov.com
● Blog: http://nikolay.samokhvalov.com
● XMPP/GTalk: samokhvalov@gmail.com
● Skype: samokhvalov & postgresmen
● +7 905 783 9804

PostgreSQL: промышленная разработка баз данных. Лекция 6