SQLAlchemy查询过滤器在时间段为30分钟时缓慢两次

时间:2014-02-05 10:35:13

标签: python postgresql sqlalchemy flask flask-sqlalchemy

我有一个Author类,在Flask应用中有很多Post个。我试图在最后一分钟,最后30分钟和最后24小时检索每位作者的帖子。这些是我正在使用的查询:

now = datetime.now()

q = db.session.query(Post)
q = q.join(Post.author)
q = q.filter(Author.id == author.id)
q = q.filter(Post.created.between(now-timedelta(minutes=1), now))
posts_in_last_minute = q.count()

q = db.session.query(Post)
q = q.join(Post.author)
q = q.filter(Author.id == author.id)
q = q.filter(Post.created.between(now-timedelta(minutes=30), now))
posts_in_last_half_hour = q.count()

q = db.session.query(Post)
q = q.join(Post.author)
q = q.filter(Author.id == author.id)
q = q.filter(Post.created.between(now-timedelta(days=1), now))
posts_in_last_day = q.count()

这是由我的作者索引视图调用的,该视图显示了包含每个人的这三个计数的表。

第一次和第三次查询需要大约100ms。对于一些作者而言,奇怪的是第二个查询,超过30分钟的时间段,通常需要5到35秒。如果不一致,非常频繁地发生这种情况,并且总是需要很长时间的30分钟时间段查询。这是一个耗时20秒的查询的回声:

2014-02-05 10:16:33,187 INFO sqlalchemy.engine.base.Engine SELECT count(*) AS count_1 
FROM (SELECT posts.created AS posts_created 
FROM posts JOIN post_author_join AS post_author_join_1 ON posts.id = post_author_join_1.post_id JOIN authors ON authors.id = post_author_join_1.author_id 
WHERE author.id = %(id_1)s AND post.created BETWEEN %(created_1)s AND %(created_2)s) AS anon_1
2014-02-05 10:16:33,187 INFO sqlalchemy.engine.base.Engine {'id_1': 6, 'created_2': datetime.datetime(2014, 2, 5, 10, 16, 32, 361308), 'created_1': datetime.datetime(2014, 2, 5, 9, 46, 32, 361308)}
2014-02-05 10:16:57,966 INFO sqlalchemy.engine.base.Engine SELECT count(*) AS count_1 
FROM (SELECT posts.created AS posts_created 

有没有人有类似的东西或知道替代方法的经验? DB是postgresql,我正在使用SQLAlchemy。

- 开始包含pgAdmin查询计划 -

使用pgAdmin我可以看到两者都有相同的查询计划。使用此接口也需要20ms。是否有可能有时查询计划不同,我应该等待慢查询?

"Aggregate  (cost=8925.80..8925.81 rows=1 width=0)"
"  ->  Nested Loop  (cost=7164.08..8925.79 rows=1 width=0)"
"        ->  Hash Join  (cost=7164.08..8923.69 rows=1 width=4)"
"              Hash Cond: (post_author_join_1.post_id = post.id)"
"              ->  Seq Scan on post_author_join post_author_join_1  (cost=0.00..1563.47 rows=52302 width=8)"
"                    Filter: (author_id = 2)"
"              ->  Hash  (cost=7164.07..7164.07 rows=1 width=4)"
"                    ->  Seq Scan on posts  (cost=0.00..7164.07 rows=1 width=4)"
"                          Filter: ((created >= '2014-02-05 10:16:32.361'::timestamp without time zone) AND (created <= '2014-02-05 09:46:32.361'::timestamp without time zone))"
"        ->  Seq Scan on authors  (cost=0.00..2.09 rows=1 width=4)"
"              Filter: (id = 2)"


"Aggregate  (cost=8941.72..8941.73 rows=1 width=0)"
"  ->  Nested Loop  (cost=7180.00..8941.71 rows=1 width=0)"
"        ->  Hash Join  (cost=7180.00..8939.61 rows=1 width=4)"
"              Hash Cond: (post_author_join_1.post_id = posts.id)"
"              ->  Seq Scan on post_author_join post_author_join_1  (cost=0.00..1563.47 rows=52302 width=8)"
"                    Filter: (author_id = 2)"
"              ->  Hash  (cost=7179.99..7179.99 rows=1 width=4)"
"                    ->  Seq Scan on posts  (cost=0.00..7179.99 rows=1 width=4)"
"                          Filter: ((created >= '2014-02-05 10:16:32.361'::timestamp without time zone) AND (created <= '2014-02-05 10:15:32.361'::timestamp without time zone))"
"        ->  Seq Scan on authors  (cost=0.00..2.09 rows=1 width=4)"
"              Filter: (id = 2)"

0 个答案:

没有答案