Повнотекстові запити щодо цієї бази даних (зберігання квитків RT ( Tracker Tracker )), здається, займають дуже багато часу. Таблиця вкладених файлів (що містить дані повного тексту) становить приблизно 15 Гб.
Схема бази даних така, вона становить приблизно 2 мільйони рядків:
rt4 = # \ d + вкладення Таблиця "public.attachments" Стовпець | Тип | Модифікатори | Зберігання | Опис ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | ціле | not null nextval ('attachments_id_seq' :: regclass) | рівнина | трансакціонід | ціле | не нульовий | рівнина | батьківський | ціле | не нуль за замовчуванням 0 | рівнина | messageid | характер варіюється (160) | | розширений | предмет | характер варіюється (255) | | розширений | ім'я файлу | характер варіюється (255) | | розширений | змістовий тип | характер варіюється (80) | | розширений | змістовне кодування | характер варіюється (80) | | розширений | зміст | текст | | розширений | заголовки | текст | | розширений | творець | ціле | не нуль за замовчуванням 0 | рівнина | створено | позначка часу без часового поясу | | рівнина | contentindex | цвектор | | розширений | Індекси: "PRIMARY KEY" "attachments_pkey", btree (id) "вкладення1" btree (батьківський) "attachments2" btree (трансакціонід) "вкладення3" btree (батьківський, трансакціонідний) "contentindex_idx" джин (contentindex) Має OID: ні
Я можу дуже швидко запитати власну базу даних (<1s) із запитом, таким як:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Однак, коли RT виконує запит, який повинен виконувати пошук по індексу повного тексту за тією ж таблицею, на виконання зазвичай потрібні сотні секунд. Вихід аналізу запитів виглядає наступним чином:
Запит
SELECT COUNT(DISTINCT main.id)
FROM Tickets main
JOIN Transactions Transactions_1 ON ( Transactions_1.ObjectType = 'RT::Ticket' )
AND ( Transactions_1.ObjectId = main.id )
JOIN Attachments Attachments_2 ON ( Attachments_2.TransactionId = Transactions_1.id )
WHERE (main.Status != 'deleted')
AND ( ( ( Attachments_2.ContentIndex @@ plainto_tsquery('frobnicate') ) ) )
AND (main.Type = 'ticket')
AND (main.EffectiveId = main.id);
EXPLAIN ANALYZE
вихід
ПИТАННЯ ПЛАНУ -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Сукупна (вартість = 51210.60..51210.61 рядків = 1 ширина = 4) (фактичний час = 477778.806..477778.806 рядів = 1 петля = 1) -> Вкладена петля (вартість = 0,00..51210,57 рядків = 15 ширина = 4) (фактичний час = 17943.986..477775.174 рядки = 4197 петлі = 1) -> Вкладена петля (вартість = 0,00..40643,08 рядків = 6507 ширина = 8) (фактичний час = 8,526..20610,380 рядків = 1714818 циклів = 1) -> Повторне сканування на головних квитках (вартість = 0,00..9818,37 рядків = 598 ширина = 8) (фактичний час = 0,008..256,042 рядки = 96990 циклів = 1) Фільтр: (((статус) :: текст "видалено" :: текст) І (id = ефективні) І ((тип) :: текст = "квиток": текст)) -> Сканування покажчика за допомогою транзакцій1 для транзакцій транзакцій_1 (вартість = 0,00..51,36 рядків = 15 ширина = 8) (фактичний час = 0,102..0,202 рядки = 18 циклів = 96990) Індекс Cond: (((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Індексувати сканування за допомогою вкладених файлів2 для вкладених файлів_2 (вартість = 0,00..1,61 рядка = 1 ширина = 4) (фактичний час = 0,266..0,266 рядків = 0 циклів = 1714818) Індекс Cond: (transactionid = сделки_1.id) Фільтр: (contentindex @@ plainto_tsquery ('frobnicate' :: текст)) Загальна тривалість виконання: 477778,883 мс
Наскільки я можу сказати, проблема виглядає в тому, що він не використовує індекс, створений у contentindex
полі ( contentindex_idx
), скоріше це робить фільтр за великою кількістю відповідних рядків у таблиці вкладень. Підрахунок рядків у виведенні пояснення також здається дико неточним навіть після останнього ANALYZE
: приблизні рядки = 6507 фактичних рядків = 1714818.
Я не дуже впевнений, куди йти далі з цим.