PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Optymalizacja wyszukiwania pełnotekstowego Django - Postgres

Jak już sugerował @knbk, aby poprawić wydajność, musisz przeczytać Skuteczność wyszukiwania pełnotekstowego sekcja w Django dokumentacja.

W swoim kodzie możesz dodać pole wektora wyszukiwania w swoim modelu z powiązanym indeksem GIN i zestawem zapytań z nową metodą aktualizacji pola:

from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVector, SearchVectorField
from django.db import models
from postgres_copy import CopyQuerySet


class AddressesQuerySet(CopyQuerySet):

    def update_search_vector(self):
        return self.update(search_vector=SearchVector(
            'number', 'street', 'unit', 'city', 'region', 'postcode'
        ))


class Addresses(models.Model):
    date_update = models.DateTimeField(auto_now=True, null=True)
    longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True)
    latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True)
    number = models.CharField(max_length=16, null=True, default='')
    street = models.CharField(max_length=60, null=True, default='')
    unit = models.CharField(max_length=50, null=True, default='')
    city = models.CharField(max_length=50, null=True, default='')
    district = models.CharField(max_length=10, null=True, default='')
    region = models.CharField(max_length=5, null=True, default='')
    postcode = models.CharField(max_length=5, null=True, default='')
    addr_id = models.CharField(max_length=20, unique=True)
    addr_hash = models.CharField(max_length=20, unique=True)
    search_vector = SearchVectorField(null=True, editable=False)

    objects = AddressesQuerySet.as_manager()

    class Meta:
        indexes = [
            GinIndex(fields=['search_vector'], name='search_vector_idx')
        ]

Możesz zaktualizować swoje nowe pole wektora wyszukiwania za pomocą nowej metody queryset:

>>> Addresses.objects.update_search_vector()
UPDATE "addresses_addresses"
SET "search_vector" = to_tsvector(
  COALESCE("addresses_addresses"."number", '') || ' ' ||
  COALESCE("addresses_addresses"."street", '') || ' ' ||
  COALESCE("addresses_addresses"."unit", '') || ' ' ||
  COALESCE("addresses_addresses"."city", '') || ' ' ||
  COALESCE("addresses_addresses"."region", '') || ' ' ||
  COALESCE("addresses_addresses"."postcode", '')
)

Jeśli wykonasz zapytanie i przeczytasz wyjaśnienie, zobaczysz używany indeks GIN:

>>> print(Addresses.objects.filter(search_vector='north').values('id').explain(verbose=True))
EXPLAIN (VERBOSE true)
SELECT "addresses_addresses"."id"
FROM "addresses_addresses"
WHERE "addresses_addresses"."search_vector" @@ (plainto_tsquery('north')) = true [0.80ms]
Bitmap Heap Scan on public.addresses_addresses  (cost=12.25..16.52 rows=1 width=4)
  Output: id
  Recheck Cond: (addresses_addresses.search_vector @@ plainto_tsquery('north'::text))
  ->  Bitmap Index Scan on search_vector_idx  (cost=0.00..12.25 rows=1 width=0)
        Index Cond: (addresses_addresses.search_vector @@ plainto_tsquery('north'::text))

Jeśli chcesz głębiej pogłębić, możesz przeczytać artykuł które napisałem na ten temat:

Pełny tekst Szukaj w Django za pomocą PostgreSQL

Aktualizacja

Próbowałem wykonać wygenerowanie SQL przez Django ORM:http://sqlfiddle.com/#!17 /f9aa9/1



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy przypadek ma znaczenie, gdy „auto” ładuje dane z S3 do tabeli Redshift?

  2. Pobierz wartość kolumny poprzedniego wiersza w postgresie nie może użyć funkcji okna w UPDATE

  3. Jak dodać kolumnę, która nie zezwala na wartości null w bazie danych Postgresql?

  4. Przewodnik po partycjonowaniu danych w PostgreSQL

  5. Jak pokazać dziadka w hierarchii sql?