Повнотекстові запити щодо цієї бази даних (зберігання квитків 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.
Я не дуже впевнений, куди йти далі з цим.