我有一个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)"