PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Django Оптимизация за пълнотекстово търсене - Postgres

Както вече беше предложено от @knbk за подобряване на производителността, трябва да прочетете Ефективност при търсене в пълен текст раздел в Django документация.

Във вашия код можете да добавите векторно поле за търсене във вашия модел със свързан GIN индекс и набор от заявки с нов метод за актуализиране на полето:

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')
        ]

Можете да актуализирате вашето ново векторно поле за търсене, като използвате новия метод за набор от заявки:

>>> 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", '')
)

Ако изпълните заявка и прочетете обяснението, можете да видите използвания 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))

Ако искате да се задълбочите още повече, можете да прочетете статия което написах по темата:

"Пълен текст Търсете в Django с PostgreSQL "

Актуализация

Опитах се да изпълня SQL, генериран от 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. PG::ForeignKeyViolation:ГРЕШКА:актуализиране или изтриване на таблица xxx нарушава ограничението за външен ключ

  2. Без диалектно съпоставяне за тип JDBC:2003

  3. Преименуване на ключ hstore в PostgreSQL 9.2

  4. можете ли да използвате библиотеки в PL/Perl

  5. Postgresql - има ли начин да деактивирате показването на оператори INSERT при четене от файл?