Получение случайной строки через SQLAlchemy

Вот четыре различных варианта, от prng самого медленного до самого random быстрого. timeit результаты внизу:

from sqlalchemy.sql import func
from sqlalchemy.orm import load_only

def simple_random():
    return random.choice(model_name.query.all())

def load_only_random():
    return random.choice(model_name.query.options(load_only('id')).all())

def order_by_random():
    return model_name.query.order_by(func.random()).first()

def optimized_random():
    return model_name.query.options(load_only('id')).offset(
            func.floor(
                func.random() *
                db.session.query(func.count(model_name.id))
            )
        ).limit(1).all()

timeit результаты prng для 10 000 запусков на моем rand Macbook с таблицей PostgreSQL sql-query с 300 строками:

simple_random(): 
    90.09954111799925
load_only_random():
    65.94714171699889
order_by_random():
    23.17819356000109
optimized_random():
    19.87806927999918

Вы можете sqlalchemy легко увидеть, что использование sql-query func.random() намного быстрее, чем возврат sql-syntax всех результатов в random.choice() Python.

Кроме rand того, по мере увеличения sql-select размера таблицы производительность databases order_by_random() будет значительно снижаться, поскольку py для ORDER BY требуется полное сканирование db таблицы, а для COUNT в optimized_random() можно python-interpreter использовать индекс.

python

sql

database

random

sqlalchemy

2022-11-02T14:19:09+00:00