2

MySQL テーブルに 2M を超えるレコードを持つ独自の City モデル (django-cities-light ではない) があります。オートコンプリート フィールドに入力し始めるたびに、htop テーブルの CPU 負荷が mysqld プロセスで 200% を超えて跳ね上がるため、オートコンプリートごとにスクリプトがテーブルを要求しているように見えます。

これを避けるためにテーブルを memcache に入れたいのですが、これまでのところ次のとおりです。

autocomplete_light_registry.py

import autocomplete_light
from django.core.cache import cache, InvalidCacheBackendError
from cities.models import City

def prepare_choices(model):
    key = "%s_autocomplete" % model.__name__.lower()
    try:
        qs = cache.get(key)
        if cache.get(key): # return if not expired
            return qs
    except InvalidCacheBackendError:
        pass
    qs = model.objects.all()     # populate cache
    cache.set(key, qs, 60*60*24) # if expired or not set
    return qs

class CityAutocomplete(autocomplete_light.AutocompleteModelBase):
    search_fields = ['city_name']
    choices = prepare_choices(City)
autocomplete_light.register(City, CityAutocomplete)

しかし、それでも mysql を要求し続けます。

助言がありますか?

アップデート

django シェルで都市テーブルのキャッシュを設定しようとしましたが、プロセスがセグメンテーション違反メッセージで中断します。

>>> from django.core.cache import cache
>>> qs = City.objects.all()
>>> qs.count()
2246813
>>> key = 'city_autocomplete'
>>> cache.set(key, qs, 60*60*24)
Segmentation fault

しかし、小さいテーブルをキャッシュに入れることができたので、この問題を克服したいと思っているので、まだ答えが必要です。

4

1 に答える 1

3

cache.set(key, qs, 60*60*24) セグメンテーション違反

これは、クエリが大きすぎるために発生しました。フィルタリングした後、これをキャッシュする必要があります。

これが私がこれをした方法です。完璧ではありませんが、500 要素でうまく機能しました。

def get_autocomplete(request):
    if request.is_ajax():
        q = request.GET.get('term', '')
        results_list = MY_model.objects.filter(title__contains=q).all()
        results = []
        for result in results_list:
            results.append(result)
        data = json.dumps(results)
    else:
        data = 'Nothing to see here!'
    mimetype = 'application/json'
    return http.HttpResponse(data, mimetype)

これはネットのどこかで見つけました。

残りは画面から飛び出すため、最初の 10 個の要素が必要です。

于 2016-11-17T13:33:47.720 に答える