Skip to main content

A fast Django .count() implementation for large tables.

Project description

Django Fast Count

PyPI GitHub license GitHub last commit PyPI - Downloads GitHub stars Ko-fi Link

A fast Django .count() implementation for large tables.

Summary

For most databases, when a table begins to exceed several million rows, the performance of the default QuerySet.count() implementation begins to be poor. Sometimes it is so poor that a count is the slowest query in a view by several orders of magnitude. Since the Django admin app uses .count() on every list page, this can be annoying at best or unusable at worst.

This package provides a fast, plug-and-play, database agnostic count implementation. To use it, you just need to have django-fast-count installed and then override your Model's ModelManager with FastCountManager.

After FastCountManager is on your Model, fast counts are immediately activate. Precaching for all .count() queries is triggered automatically on every .count() query in a forked background process.

To proactively precache and clean expired counts, run precache_fast_counts in a regularly scheduled task.

Installation

pip install django-fast-count
# settings.py

INSTALLED_APPS = [
    # ...
    'django.contrib.contenttypes',
    'django_fast_count',
]
python manage.py migrate

Usage

from datetime import timedelta

from django.db.models import Model, BooleanField
from django_fast_count.managers import FastCountManager


class YourModel(Model):
    your_field = BooleanField(default=False)

    # By default, only .all() is precached
    objects = FastCountManager(
        precache_count_every=timedelta(hours=1),  # Defaults to 10 minutes
        cache_counts_larger_than=100_000,  # Defaults to 1,000,000
        expire_cached_counts_after=timedelta(hours=1),  # Defaults to 10 minutes
    )

    # To cache additional querysets, override the `fast_count_querysets`
    @classmethod
    def fast_count_querysets(cls):
        return [
            cls.objects.filter(your_field=True),
            cls.objects.filter(your_field=False),
        ]

FastCountManager

The FastCountManager is a subclass of the default django ModelManager that overrides .count() to use utilize cached counts. It has two main caching mechanisms:

  1. Precaching of select .count() queries every specified interval
  2. Retroactive caching of any .count() queries that return a count over a threshold

It has 3 initialization parameters:

  1. precache_count_every - The frequency with which to precache select .count() queries
  2. cache_counts_larger_than - The minimum count at which to retroactively cache all other .count() queries
  3. expire_cached_counts_after - The frequency at which to expire cached .count() queries

By default, FastCountManager will only precache .all() queries. To specify additional QuerySets to precache, implement a fast_count_querysets method on your model that returns a list of QuerySets. Each of those QuerySets will be counted every precache_count_every and cached for use on future matching .count() queries.

Precaching Process

Precaching of counts is performed regularly by a management command that is called from a forked process. The forked process is started every precache_count_every from any .count() query performed on the model.

Typically, this means that precaching is performed in a background task on your web server, so if your django deploy is serverless, the precaching process may end early and not function properly.

Deadlock control over the precaching scheduler is implemented with atomic transactions so that multiple .count() queries do not simultaneously run the precaching process.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_fast_count-0.1.3.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_fast_count-0.1.3-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file django_fast_count-0.1.3.tar.gz.

File metadata

  • Download URL: django_fast_count-0.1.3.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.4

File hashes

Hashes for django_fast_count-0.1.3.tar.gz
Algorithm Hash digest
SHA256 513a986ca1351f3b044405aadd8f3c7954a174027f945640cfcafde5cd54ac99
MD5 779f847a5169089179c4ec5a51452d36
BLAKE2b-256 560a3a5319b341a8b90df1e79eed95c1acab272c6b083e48deb3a9e20720adfe

See more details on using hashes here.

File details

Details for the file django_fast_count-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for django_fast_count-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8ffc63ba4d11e465a93bb66c5bf84e9ee14cc5979fb108f7bceec7aa22e6e5cf
MD5 cb2e3a223e189d73b18e52cdc622c57a
BLAKE2b-256 eb2ea8cf5e90ff7958582d43341f3e7a483638f8da9f79983ca18913b2ae6842

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page