我有一个~10M记录的MySQL表,我使用SqlAlchemy进行交互.我发现对这个表的大型子集的查询将占用太多内存,即使我认为我使用的是内置生成器,智能地获取数据集的一口大小的块:
for thing in session.query(Things):
analyze(thing)
Run Code Online (Sandbox Code Playgroud)
为了避免这种情况,我发现我必须构建自己的迭代器,这些迭代器会以块的形式出现:
lastThingID = None
while True:
things = query.filter(Thing.id < lastThingID).limit(querySize).all()
if not rows or len(rows) == 0:
break
for thing in things:
lastThingID = row.id
analyze(thing)
Run Code Online (Sandbox Code Playgroud)
这是正常的还是有关于SA内置发电机我缺少的东西?
这个问题的答案似乎表明内存消耗是不可预期的.
我有一个表,我在LIMIT和OFFSET之前进行ORDER BY,以便进行分页.
在ORDER BY列上添加索引会对性能产生巨大影响(与小LIMIT结合使用时).在一个500,000行表中,只要有一个小的LIMIT,我看到增加索引的10,000倍改进.
但是,索引对高OFFSET(即我的分页中的后续页面)没有影响.这是可以理解的:b树索引可以很容易地从头开始按顺序迭代但不能找到第n个项.
似乎有用的是计算的b树索引,但我不知道PostgreSQL中对这些的支持.还有其他解决方案吗?似乎优化大型OFFSET(特别是在分页用例中)并不是那么不寻常.
不幸的是,PostgreSQL手册简单地说"OFFSET子句跳过的行仍然必须在服务器内部计算;因此大的OFFSET可能效率低下."
如果执行以下数据库(postgres)查询,则第二次调用要快得多.
我想第一个查询很慢,因为操作系统(linux)需要从磁盘获取数据.第二个查询受益于文件系统级别和postgres中的缓存.
有没有办法优化数据库,以便在第一次调用时快速获得结果?
第一次通话(慢)
foo3_bar_p@BAR-FOO3-Test:~$ psql
foo3_bar_p=# explain analyze SELECT "foo3_beleg"."id", ... FROM "foo3_beleg" WHERE
foo3_bar_p-# (("foo3_beleg"."id" IN (SELECT beleg_id FROM foo3_text where
foo3_bar_p(# content @@ 'footown'::tsquery)) AND "foo3_beleg"."belegart_id" IN
foo3_bar_p(# ('...', ...));
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=75314.58..121963.20 rows=152 width=135) (actual time=27253.451..88462.165 rows=11 loops=1)
-> HashAggregate (cost=75314.58..75366.87 rows=5229 width=4) (actual time=16087.345..16113.988 rows=17671 loops=1)
-> Bitmap Heap Scan on foo3_text (cost=273.72..75254.67 rows=23964 width=4) (actual time=327.653..16026.787 rows=27405 loops=1)
Recheck Cond: (content @@ '''footown'''::tsquery)
-> Bitmap Index Scan on …Run Code Online (Sandbox Code Playgroud) 以下架构:
CREATE TABLE employees (
name CHAR,
PRIMARY KEY id INT
);
Run Code Online (Sandbox Code Playgroud)
该表按 id 排序
表中有 1-100 的 100 个唯一 id。
| name | id |
|---------|----|
| Lynne | 1 |
| Johnny | 2 |
| D'Andra | 3 |
| Kimmel | 4 |
| ... |
Run Code Online (Sandbox Code Playgroud)
获取 id 大于或等于 3 的 10 个人。
select name from employees order by id limit 10 offset 3使用or会更快吗select name from employees where id >= …
mysql ×2
performance ×2
postgresql ×2
sql ×2
database ×1
disk-io ×1
limit ×1
python ×1
range ×1
sqlalchemy ×1