Wydaje się, że wykonywanie pełnotekstowych zapytań w tej bazie danych (przechowywanie biletów RT ( Request Tracker )) trwa bardzo długo. Tabela załączników (zawierająca dane pełnotekstowe) ma około 15 GB.
Schemat bazy danych jest następujący, ma około 2 milionów wierszy:
rt4 = # \ d + załączniki Tabela „public.attachments” Kolumna | Wpisz | Modyfikatory | Przechowywanie | Opis ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | liczba całkowita | not null default nextval ('attachments_id_seq' :: regclass) | zwykły | transakcja | liczba całkowita | nie zerowy | zwykły | rodzic | liczba całkowita | nie jest wartością domyślną 0 | zwykły | messageid | różniące się postaciami (160) | | rozszerzony | temat | różniące się postaciami (255) | | rozszerzony | nazwa pliku | różniące się postaciami (255) | | rozszerzony | typ zawartości | różniące się postaciami (80) | | rozszerzony | kodowanie zawartości | różniące się postaciami (80) | | rozszerzony | treść | tekst | | rozszerzony | nagłówki | tekst | | rozszerzony | twórca | liczba całkowita | nie jest wartością domyślną 0 | zwykły | utworzony | sygnatura czasowa bez strefy czasowej | | zwykły | contentindex | tsvector | | rozszerzony | Indeksy: „attachments_pkey” KLUCZ PODSTAWOWY, btree (id) „attachments1” btree (rodzic) „attachments2” btree (transactionid) „attachments3” btree (rodzic, transakcja) „contentindex_idx” gin (contentindex) Ma identyfikatory OID: nie
Mogę bardzo szybko wykonać zapytanie do bazy danych (<1s) za pomocą zapytania takiego jak:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Jednak gdy RT uruchamia zapytanie, które ma wykonać wyszukiwanie pełnotekstowe indeksu w tej samej tabeli, zwykle zajmuje setki sekund. Dane wyjściowe analizy zapytania są następujące:
Pytanie
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
wynik
PLAN ZAPYTANIA -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Agregat (koszt = 51210.60..51210.61 wierszy = 1 szerokość = 4) (czas rzeczywisty = 477778.806..477778.806 wierszy = 1 pętla = 1) -> Zagnieżdżona pętla (koszt = 0,00..51210,57 wierszy = 15 szerokości = 4) (czas rzeczywisty = 17943.986..477775.174 wierszy = 4197 pętli = 1) -> Zagnieżdżona pętla (koszt = 0,00..40643,08 wierszy = 6507 szerokość = 8) (czas rzeczywisty = 8,526..20610,380 wierszy = 1714818 pętli = 1) -> Seq Scan on bilety główne (koszt = 0,00..98188,37 wierszy = 598 szerokość = 8) (czas rzeczywisty = 0,008..256,042 wierszy = 96990 pętli = 1) Filtr: (((status) :: tekst „usunięty” :: tekst) ORAZ (id = efektywny) ORAZ ((typ) :: tekst = „bilet” :: tekst)) -> Skanowanie indeksu przy użyciu transakcji1 na transakcjach transakcyjnych_1 (koszt = 0,00..51,36 wierszy = 15 szerokości = 8) (rzeczywisty czas = 0,102..0,202 wierszy = 18 pętli = 96990) Indeks Cond: (((typ obiektu) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Indeksuj skanowanie za pomocą załączników2 na załącznikach attachments_2 (koszt = 0,00..1,61 wiersza = 1 szerokość = 4) (rzeczywisty czas = 0,266..0,266 wierszy = 0 pętli = 1714818) Indeks War: (transakcja = transakcje_1.id) Filtr: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Całkowity czas działania: 477778,883 ms
O ile mi wiadomo, wydaje się, że problem polega na tym, że nie używa on indeksu utworzonego w contentindex
polu ( contentindex_idx
), a raczej filtruje dużą liczbę pasujących wierszy w tabeli załączników. Liczby ANALYZE
wierszy w wynikach wyjaśniania również wydają się bardzo niedokładne, nawet po ostatnich : szacowane wiersze = 6507 rzeczywistych wierszy = 1714818.
Nie jestem do końca pewien, co dalej z tym zrobić.