読者です 読者をやめる 読者になる 読者になる

Keep It Real BLOG

ソフトウェアエンジニア。1児の父。 酒、ラーメン、サッカー好き。旅行も好きですが、普段は出不精で大抵たまプラーザ界隈に居ます。

Djangoで100m以内のデータを近距離順にソートする処理を爆速化

f:id:naohide_a:20151202202517j:plain

現在、位置情報を使用したシステムを作っていて、そこで100m以内の情報を取ってくる+近距離順にソートする必要性があり、単純にデータ取得+ソートを掛けたところ、indexが効かなく非常に処理が遅かったので、その時の対処方法を残しておきたいと思います。

DBはPostgreを使っていることを前提にします。

PointFieldにgeographyオプションを使う

point = models.PointField(geography=True, verbose_name=u'座標')

最初、何もオプションを設定していなかったのですが、geographyオプションを設定するようにしました。 また、あとからオプションを設定した場合、migrationが必要です。

distance_lteをやめてdwithinを使う

Model.objects.distance(point).filter(
    point__dwithin=(point, D(m=100))
).order_by('distance')

最初は、dwithinの変わりにdistance_lteを指定していたのですが、これだとindexが上手く効かず遅くなる原因になっていました。 dwithinは、PointFieldgeography=Trueが設定されていないと使用することが出来ません。

やったことはこれら2つで終わりです。 ですが、これら2つで、100倍近くスピードアップし、爆速化することが出来ました!