2015-06-18 12 views
5

Mam dużą definicję indeksu, która trwa zbyt długo indeksowania. Podejrzewam, że główny problem jest spowodowany wygenerowaniem wielu LEWYCH ZEWNĘTRZNYCH POŁĄCZEŃ.Myślenie wydajności indeksowania Sphinx

Widziałem this question, ale nie mogę znaleźć dokumentacji dotyczącej korzystania z source: :query, która wydaje się być częścią rozwiązania.

Moja definicja indeksu i otrzymaną zapytań można znaleźć tutaj: https://gist.github.com/jonsgold/fdd7660bf8bc98897612

Jak mogę zoptymalizować wygenerowane zapytanie działać szybciej podczas indeksowania?

Odpowiedz

2

"Standardowym" rozwiązaniem Sfinksa byłoby użycie zapytań dystansowych.

http://sphinxsearch.com/docs/current.html#ex-ranged-queries

... dzielenie się zapytanie do wielu małych części, więc serwer bazy danych ma większą szansę bycia w stanie uruchomić kwerendę (raczej niż jeden ogromny zapytań)

Ale nie mam pojęcia, jak skutecznie to umożliwić w Myślącym Sfinksie. Nic nie widać w dokumentacji. Może ci pomóc edytować plik sphinx.conf, ale także nie wiesz, jak TS poradzi sobie z ręczną edycją pliku konfiguracyjnego.

+0

Dzięki, brzmi to jak dobre miejsce do rozpoczęcia. – Jonathan

+0

Wygląda na to, że połączone pola lepiej rozwiązałyby mój problem z indeksowaniem wydajności: http://sphinxsearch.com/docs/current.html#conf-sql-joined-field. Każdy pomysł, jak to zaimplementować w TS? – Jonathan

+0

Przyglądając się bliżej najważniejszemu ogłoszeniu, masz już zapytanie o zasięg, czy edytowałeś sedno? Jeśli nie, to tego nie zauważyłem. Połączone pola są również przydatne, przepraszam, nie wiem, czy TS może włączyć ich użycie. – barryhunter

0

To jest rozwiązanie, które działało najlepiej (od linked question). Zasadniczo można usunąć fragment głównej kwerendy sql_query i zdefiniować go osobno jako plik sql_joined_field w pliku .

Ważne jest, aby dodać wszystkie istotne warunki sql do każdego sql_joined_field (takie jak sharding indexes by modulo na ID). Oto nowa definicja:

ThinkingSphinx::Index.define(
    :incident, 
    with: :active_record, 
    delta?: false, 
    delta_processor: ThinkingSphinx::Deltas.processor_for(ThinkingSphinx::Deltas::ResqueDelta) 
) do 
    indexes "SELECT incidents.id * 51 + 7 AS id, sites.name AS site FROM incidents LEFT OUTER JOIN sites ON sites.id = site_id WHERE incidents.deleted = 0 AND EXISTS (SELECT id FROM accounts WHERE accounts.status = 'enabled' AND incidents.account_id = id) ORDER BY id", as: :site, source: :query 
    ... 
    has 
    ... 
end 

ThinkingSphinx::Index.define(
    :incident, 
    with: :active_record, 
    delta?: true, 
    delta_processor: ThinkingSphinx::Deltas.processor_for(ThinkingSphinx::Deltas::ResqueDelta) 
) do 
    indexes "SELECT incidents.id * 51 + 7 AS id, sites.name AS site FROM incidents LEFT OUTER JOIN sites ON sites.id = site_id WHERE incidents.deleted = 0 AND incidents.delta = 1 AND EXISTS (SELECT id FROM accounts WHERE accounts.status = 'enabled' AND incidents.account_id = id) ORDER BY id", as: :site, source: :query 
    ... 
    has 
    ... 
end 

Magia który definiuje pole site jako oddzielny zapytania jest opcja source: :query na końcu linii.

Uwaga: definicja indeksu podstawowego ma parametr delta?: false, natomiast definicja indeksu delta ma parametr delta?: true. Tak więc mogłem użyć warunku WHERE incidents.delta = 1 w indeksie delta i odfiltrować nieistotne rekordy.

Znalazłem sharding, który nie działał lepiej, więc powróciłem do jednego zunifikowanego indeksu.

Zobacz całą definicję indeksu tutaj: https://gist.github.com/jonsgold/05e2aea640320ee9d8b2.

Ważne do zapamiętania!

Przesunięcie identyfikatora dokumentu Sphinx musi być obsługiwane ręcznie. Oznacza to, że po dodaniu lub usunięciu indeksu dla innego modelu zmieni się mój obliczony identyfikator dokumentu. To musi być zaktualizowane.

Tak więc, w moim przykładzie, jeśli dodałem indeks dla innego modelu (nie :incident), musiałbym uruchomić rake ts:configure, aby znaleźć moje nowe przesunięcie i zmienić odpowiednio incidents.id * 51 + 7.

Powiązane problemy