我在Postgres 9.2中有下表(简化形式)
CREATE TABLE log (
log_date DATE,
user_id INTEGER,
payload INTEGER
);
Run Code Online (Sandbox Code Playgroud)
它每个用户和每天最多包含一条记录.每天将有大约500,000条记录,为期300天.每个用户的running_total总是在增加.
我想在特定日期之前有效地检索每个用户的最新记录.我的查询是:
SELECT user_id, max(log_date), max(payload)
FROM log
WHERE log_date <= :mydate
GROUP BY user_id
Run Code Online (Sandbox Code Playgroud)
这非常慢.我也尝试过:
SELECT DISTINCT ON(user_id), log_date, payload
FROM log
WHERE log_date <= :mydate
ORDER BY user_id, log_date DESC;
Run Code Online (Sandbox Code Playgroud)
具有相同的计划,同样缓慢.
到目前为止,我在user_msg_log(aggr_date)上有一个索引,但没有多大帮助.我应该用什么其他索引来加快速度,还是以任何其他方式实现我的目标?
sql postgresql indexing greatest-n-per-group postgresql-performance
当我使用默认的enable_nestloop = true和enable_nestloop = false(~10秒)运行它时,我的查询运行速度慢了很多(约5分钟).
解释两种情况的分析结果:
机器A nestloop = true - http://explain.depesz.com/s/nkj0(~5分钟)机器a nestloop = false - http://explain.depesz.com/s/wBM(~10秒)
在另一个稍慢的机器上,复制数据库并保留默认的enable_nestloop = true需要大约20秒.
机器B nestloop = true - (~20secs)
对于上述所有情况,我确保在运行查询之前进行了ANALYZE.没有其他查询并行运行.
两台机器都在运行Postgres 8.4.机器A运行Ubuntu 10.04 32位,而机器B运行Ubuntu 8.04 32位.
这里提供了实际查询.它是一个具有许多连接的报告查询,因为数据库主要用于事务处理.
如果不采用像物化视图这样的东西,我可以做些什么来让规划师通过设置enable_nestloop = false来完成我所做的事情?
从我所做的研究来看,计划者选择看似不理想的查询的原因似乎是因为估计行与实际行之间存在巨大差异.我怎样才能让这个数字更接近?
如果我应该重写查询,我应该改变什么?
为什么规划师似乎正在为机器B做正确的事情.我应该在两台机器上进行比较?
我想通过在单个参数上传递多个值来调用函数,如下所示:
SELECT * FROM jobTitle('270,378');
Run Code Online (Sandbox Code Playgroud)
这是我的功能。
CREATE OR REPLACE FUNCTION test(int)
RETURNS TABLE (job_id int, job_reference int, job_job_title text
, job_status text) AS
$$
BEGIN
RETURN QUERY
select jobs.id,jobs.reference, jobs.job_title,
ltrim(substring(jobs.status,3,char_length(jobs.status))) as status
FROM jobs ,company c
WHERE jobs."DeleteFlag" = '0'
and c.id= jobs.id and c.DeleteFlag = '0' and c.active = '1'
and (jobs.id = $1 or -1 = $1)
order by jobs.job_title;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
有人可以提供语法帮助吗?甚至提供示例代码?