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 FastCountModelManager.

After FastCountModelManager 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 FastCountModelManager


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

    # By default, only .all() is precached
    objects = FastCountModelManager(
        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),
        ]

FastCountModelManager

The FastCountModelManager 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, FastCountModelManager 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.0.tar.gz (17.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.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_fast_count-0.1.0.tar.gz
  • Upload date:
  • Size: 17.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.0.tar.gz
Algorithm Hash digest
SHA256 a2252890095011c138b02de2249e075af64d4ff607f448ea18a09263549e5c81
MD5 6a4209d69c8a7f66be05462508b775c8
BLAKE2b-256 881ba9756ea3488746751443d30a8968637aa4507cbdf8bbf2ed79a284eeb9be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_fast_count-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad7919757d1897dfef52e0a82cafbbc61a38fd3e528bd5cc04ba3749acdddc2f
MD5 c120c7cadb1f40bff3442932aa12ecfe
BLAKE2b-256 582d450702fd51ebb42e35f4b7313c11377e5278b39d02c86356b2056099cd8e

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