在夹层CMS中搜索缓慢

时间:2018-11-04 14:58:04

标签: performance search mezzanine

在夹层CMS中搜索缓慢。我使用夹层CMS。搜索某些东西时,我发现它太慢了。 blog_blogpost的大小约为60,000条记录。

示例站点为www.chinalaw.vip

请帮助!

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:0)

它是由不区分大小写的匹配(包含)造成的,并且没有任何索引。我通过以下步骤解决了问题:

1,将区分大小写的匹配项更改为夹层中的区分大小写的匹配项。

    excluded = [reduce(iand, [~Q(**{"%s__contains" % f: t[1:]}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] == "-"]
    required = [reduce(ior, [Q(**{"%s__contains" % f: t[1:]}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] == "+"]
    optional = [reduce(ior, [Q(**{"%s__contains" % f: t}) for f in
        self._search_fields.keys()]) for t in terms if t[0:1] not in "+-"]

2,将不区分大小写的匹配项更改为django中路径django \ contrib \ admin \ options.py中的区分大小写的匹配项。

def get_search_results(self, request, queryset, search_term):
    """
    Return a tuple containing a queryset to implement the search
    and a boolean indicating if the results may contain duplicates.
    """
    # Apply keyword searches.
    def construct_search(field_name):
        if field_name.startswith('^'):
            return "%s__istartswith" % field_name[1:]
        elif field_name.startswith('='):
            return "%s__iexact" % field_name[1:]
        elif field_name.startswith('@'):
            return "%s__search" % field_name[1:]
        # Use field_name if it includes a lookup.
        opts = queryset.model._meta
        lookup_fields = field_name.split(LOOKUP_SEP)
        # Go through the fields, following all relations.
        prev_field = None
        for path_part in lookup_fields:
            if path_part == 'pk':
                path_part = opts.pk.name
            try:
                field = opts.get_field(path_part)
            except FieldDoesNotExist:
                # Use valid query lookups.
                if prev_field and prev_field.get_lookup(path_part):
                    return field_name
            else:
                prev_field = field
                if hasattr(field, 'get_path_info'):
                    # Update opts to follow the relation.
                    opts = field.get_path_info()[-1].to_opts
        # Otherwise, use the field with icontains.
        return "%s__contains" % field_name

    use_distinct = False
    search_fields = self.get_search_fields(request)
    if search_fields and search_term:
        orm_lookups = [construct_search(str(search_field))
                       for search_field in search_fields]
        for bit in search_term.split():
            or_queries = [models.Q(**{orm_lookup: bit})
                          for orm_lookup in orm_lookups]
            queryset = queryset.filter(reduce(operator.or_, or_queries))
        use_distinct |= any(lookup_needs_distinct(self.opts, search_spec) for search_spec in orm_lookups)

    return queryset, use_distinct

3,创建索引。

   CREATE EXTENSION pg_trgm;

   CREATE INDEX blog_blogpost_content_index ON blog_blogpost USING gin (title gin_trgm_ops,description gin_trgm_ops,content gin_trgm_ops,keywords_string  gin_trgm_ops);