Sql查询首先获取粘性帖子
我正在建立一个博客,我有一个问题。应该有一些粘帖。我只想先拿到粘帖,然后拿到其他的 一个有效的查询是Sql查询首先获取粘性帖子,sql,postgresql,Sql,Postgresql,我正在建立一个博客,我有一个问题。应该有一些粘帖。我只想先拿到粘帖,然后拿到其他的 一个有效的查询是 select * from ( (select *,true as st from blog where "stickyUntil" > current_timestamp) UNION all (SELECT *,false as st from blog where "stickyUntil" < current_timestamp or "stickyUntil" i
select * from
(
(select *,true as st from blog where "stickyUntil" > current_timestamp)
UNION all
(SELECT *,false as st from blog where "stickyUntil" < current_timestamp or "stickyUntil" is null )
) q
order by st desc, "stickyUntil" DESC ,publish DESC OFFEST x LIMIT z
但这将迫使在内存中对200.000行进行排序,速度不是很快
有没有办法优化它
使用两个单独的查询是否更好?
谢谢我想用一句话来避免两次过关:
select *,
CASE
WHEN "stickyUntil" > current_timestamp THEN true
ELSE false
END as st
FROM blog
ORDER BY st DESC ,publish DESC OFFEST x LIMIT z
ALTER TABLE blog
ADD COLUMN st boolean default true
Postgres支持在计算字段上创建一个有助于此处的,但有一个限制:
索引定义中使用的所有函数和运算符都必须是“不可变的”,
也就是说,他们的结果必须只取决于他们的论点,而决不取决于任何人
外部影响(如其他表的内容或当前时间)
因此,您无法为st计算编制索引。如果st的计算不需要太精确,另一个选项是将st字段添加到表中:
select *,
CASE
WHEN "stickyUntil" > current_timestamp THEN true
ELSE false
END as st
FROM blog
ORDER BY st DESC ,publish DESC OFFEST x LIMIT z
ALTER TABLE blog
ADD COLUMN st boolean default true
st作为常规列:
CREATE INDEX sti ON blog(st)
并定期运行:
UPDATE blog
SET st = false
WHERE st = true
AND "stickyUntil" < current_timestamp
更新博客
设置st=false
其中st=true
和“粘性直到”<当前时间戳
但是,让一个轮询过程进行更新比直接查询的吸引力要小得多。只有当您的查询速度非常慢或者对blog表有大量读取时,这才有意义 我会用一句话来避免两次通过表格:
select *,
CASE
WHEN "stickyUntil" > current_timestamp THEN true
ELSE false
END as st
FROM blog
ORDER BY st DESC ,publish DESC OFFEST x LIMIT z
ALTER TABLE blog
ADD COLUMN st boolean default true
Postgres支持在计算字段上创建一个有助于此处的,但有一个限制:
索引定义中使用的所有函数和运算符都必须是“不可变的”,
也就是说,他们的结果必须只取决于他们的论点,而决不取决于任何人
外部影响(如其他表的内容或当前时间)
因此,您无法为st计算编制索引。如果st的计算不需要太精确,另一个选项是将st字段添加到表中:
select *,
CASE
WHEN "stickyUntil" > current_timestamp THEN true
ELSE false
END as st
FROM blog
ORDER BY st DESC ,publish DESC OFFEST x LIMIT z
ALTER TABLE blog
ADD COLUMN st boolean default true
st作为常规列:
CREATE INDEX sti ON blog(st)
并定期运行:
UPDATE blog
SET st = false
WHERE st = true
AND "stickyUntil" < current_timestamp
更新博客
设置st=false
其中st=true
和“粘性直到”<当前时间戳
但是,让一个轮询过程进行更新比直接查询的吸引力要小得多。只有当您的查询速度非常慢或者对blog表有大量读取时,这才有意义 我认为您最好运行两个查询,一个用于粘性帖子,另一个用于其他帖子 SQL不保证结果的顺序,没有明确的order by。虽然工会的结果似乎都是对的,但你不能保证。这在多线程环境中变得更加明显,您不知道哪个线程将首先完成数据读取并开始返回结果
最有效的解决方法是将其作为两个不同的查询来执行。我认为最好运行两个查询,一个用于粘性帖子,另一个用于其他帖子
select *
from blog
order by
coalesce("stickyUntil", '1901-01-01'::date) < current_timestamp,
publish DESC
OFFSET x LIMIT z
SQL不保证结果的顺序,没有明确的order by。虽然工会的结果似乎都是对的,但你不能保证。这在多线程环境中变得更加明显,您不知道哪个线程将首先完成数据读取并开始返回结果
最有效的解决方法是将其作为两个不同的查询进行处理。select*
select *
from blog
order by
coalesce("stickyUntil", '1901-01-01'::date) < current_timestamp,
publish DESC
OFFSET x LIMIT z
从博客
订购人
合并(“stickyUntil”,“1901-01-01”::日期)<当前时间戳,
发布说明
偏移量x极限z
选择*
从博客
订购人
合并(“stickyUntil”,“1901-01-01”::日期)<当前时间戳,
发布说明
偏移量x极限z
这没有按应有的方式排序。如果stickyUntil datetime已过,则发布只会起作用。。。我想知道是否有一种方法可以索引订单…(哎呀,刚刚注意到我的评论重复了您已经尝试过的CASE/NULLS方法。)您是对的。如果stickyUntil通过后发布顺序优先,则它将不起作用。我将更新答案以反映这一点。这些查询是否需要cornjob?我认为在每次选择之前运行更新查询应该更快(至少比完整表扫描更快),因为会有4-5个粘滞点,因此实际更新应该很少。这是真的吗?我想知道(stickyUntil,st)上的索引是否更好??这不是它应该的排序方式。如果stickyUntil datetime已过,则发布应该只起作用。。。我想知道是否有一种方法可以索引订单…(哎呀,刚刚注意到我的评论重复了您已经尝试过的CASE/NULLS方法。)您是对的。如果stickyUntil通过后发布顺序优先,则它将不起作用。我将更新答案以反映这一点。这些查询是否需要cornjob?我认为在每次选择之前运行更新查询应该更快(至少比完整表扫描更快),因为会有4-5个粘滞点,因此实际更新应该很少。这是真的吗?我想知道(stickyUntil,st)上的索引是否更好??我想这就是我要做的。。。尽管这是个蹩脚的办法。我想使用索引,但似乎不可能随着时间戳的变化…我想这就是我要做的。。。尽管这是个蹩脚的办法。我曾想过使用索引,但随着时间戳的变化似乎不可能。您的第一个查询看起来不错。工会没有错。是否认为在应用限制之前,您拉入了太多行?那么为什么要在联合中的每个子查询中添加一个“limitz”?这会将子查询返回的整个集合限制在最多2z个记录的范围内。。然后为了确定第二次查询时的偏移量,我必须为第一次查询调用一个计数。如果有5个胶粘物,那么偏移量10应该是5。。我应该这样做吗?@Paths