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

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

    クエリを実行して説明を読むと、使用されている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))
    

    さらに深く知りたい場合は、記事を読むことができます。 私がこの件について書いたこと:

    "フルテキストPostgreSQLを使用してDjangoで検索

    更新

    Django ORMによって生成されたSQLを実行してみました: http://sqlfiddle.com/#!17 / f9aa9 / 1



    1. データベースにタイムスタンプを挿入+7日

    2. 多数の列、すべて選択すると永遠にかかります

    3. max_allowed_pa​​cketを変更せずにmysqlDBに大きな値を挿入する方法はありますか?

    4. 最近挿入されたレコードIDの配列を取得するにはどうすればよいですか?