Некоторые СУБД SQL, а именно Microsoft SQL Server, DB2 и PostgreSQL , внедрили предложение SQL: 2003 TABLESAMPLE
. В SQLAlchemy была добавлена поддержка в версии 1.1 . Это позволяет возвращать выборку таблицы, используя различные методы выборки - стандарт требует SYSTEM
и BERNOULLI
, которые возвращают желаемый приблизительный процент таблицы.
В SQLAlchemy FromClause.tablesample()
и tablesample()
используются для создания TableSample
конструкции:
# Approx. 1%, using SYSTEM method
sample1 = mytable.tablesample(1)
# Approx. 1%, using BERNOULLI method
sample2 = mytable.tablesample(func.bernoulli(1))
При использовании сопоставленных классов есть небольшая ошибка: полученный объект TableSample
должен иметь псевдоним, чтобы его можно было использовать для запроса объектов модели:
sample = aliased(MyModel, tablesample(MyModel, 1))
res = session.query(sample).all()
Поскольку многие ответы содержат критерии производительности, я также включу несколько простых тестов. Используя простую таблицу в PostgreSQL с около миллиона строк и одним целочисленным столбцом, выберите (приблизительно) 1% sample:
In [24]: %%timeit
...: foo.select().\
...: order_by(func.random()).\
...: limit(select([func.round(func.count() * 0.01)]).
...: select_from(foo).
...: as_scalar()).\
...: execute().\
...: fetchall()
...:
307 ms ± 5.72 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [25]: %timeit foo.tablesample(1).select().execute().fetchall()
6.36 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [26]: %timeit foo.tablesample(func.bernoulli(1)).select().execute().fetchall()
19.8 ms ± 381 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Прежде чем использовать метод выборки SYSTEM
, следует знать, что он выбирает страниц , а не отдельные кортежи, поэтому он может не подойти, например, для небольших таблиц.