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 contentindexpolu ( contentindex_idx), a raczej filtruje dużą liczbę pasujących wierszy w tabeli załączników. Liczby ANALYZEwierszy 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ć.