目前,在努力获得以下格式查询表格的有效方法后,我正在使用此查询......
select distinct on (symbol, date) date, symbol, value, created_time
from "test_table"
where symbol in ('symbol15', 'symbol19', 'symbol36', 'symbol54', 'symbol13', 'symbol90', 'symbol115', 'symbol145', 'symbol165', 'symbol12')
order by symbol, date, created_time desc
有了这个索引......
test_table(symbol, date, created_time)
下面是一个数据示例,用于显示我正在使用的列。真实的表是1300万行。
date symbol value created_time
2010-01-09 symbol1 101 3847474847
2010-01-10 symbol1 102 3847474847
2010-01-10 symbol1 102.5 3847475500
2010-01-10 symbol2 204 3847474847
2010-01-11 symbol1 109 3847474847
2010-01-12 symbol1 105 3847474847
2010-01-12 symbol2 206 3847474847
目前看起来80%以上的查询是基于EXPLAIN ANALYZE进行排序的。知道如何提高此查询的速度吗?我需要为每个日期和符号组合获取最新的created_time。
答案 0 :(得分:0)
由于您的where
子句仅使用列symbol
,因此不会使用您创建的索引。
我建议您在symbol
上创建一个索引:
CREATE INDEX ON test_table(symbol);
此外,这可能是编写查询的更好方法
SELECT date, symbol, MAX(created_time)
FROM "test_table"
WHERE symbol in ('symbol15', 'symbol19', 'symbol36', 'symbol54', 'symbol13', 'symbol90', 'symbol115', 'symbol145', 'symbol165', 'symbol12')
GROUP BY date, symbol
ORDER BY symbol, date
LIMIT 10;
如果可以选择,添加限制将大大提高性能。
您应该运行EXPLAIN ANALYZE SELECT...
以更好地了解使用哪些索引以及PostgreSQL如何运行查询。
答案 1 :(得分:0)
您可以考虑为此目的创建部分或筛选索引 - 但请注意,如果IN
子句通过添加更多值或添加不在筛选索引中的值而更改,则它可能不起作用。它也可能对INSERT
速度产生一些不利影响,因为索引必须评估您的INSERT
是否包含一个有趣的值 - 所以如果您正在进行大量插入操作并且可以&考虑到任何额外的惩罚,请记住这一点。您还应在索引中指定您希望date
和created_time
降序。
E.g。
CREATE INDEX test_table_ix ON test_table (symbol, date DESC, created_time DESC)
WHERE (symbol in ('symbol15', 'symbol19', 'symbol36', 'symbol54', 'symbol13', 'symbol90', 'symbol115', 'symbol145', 'symbol165', 'symbol12'));
请参阅:https://www.postgresql.org/docs/8.0/static/indexes-partial.html和https://www.postgresql.org/docs/9.6/static/indexes-ordering.html
您的查询将能够使用此索引,并且应该看到一些好处 - 请记住,此索引与某些成本相关联,并考虑您的查询是否经常运行以证明其合理性。您也可以通过将订单应用于索引来看到好处。
答案 2 :(得分:0)
如果没有正确测试超过1300万行的能力,那么问题始终是建立“最新”所需的排序。虽然我有点不愿意在这里提出这个问题, row_number()over()通常是一种很好的技术来达到“最新”。
模仿你执行排序以建立“最新”的方式的索引最有可能提供帮助,所以我希望在符号,日期,created_time desc 的索引中有用。
select date, symbol, value, created_time
from (select date, symbol, value, created_time
, row_number() over(partition by symbol, date order by created_time DESC) rn
from test_table
where symbol in ('symbol15', 'symbol19', 'symbol36', 'symbol54', 'symbol13', 'symbol90', 'symbol115', 'symbol145', 'symbol165', 'symbol12')
) d
where rn = 1
order by symbol, date, created_time desc
;
答案 3 :(得分:0)
您使用的索引已经是最好的了。由于您未显示explain analyze
输出,我建议您尝试使用values
语法:
select distinct on (symbol, date) date, symbol, value, created_time
from test_table
where symbol in (values ('symbol15'), ('symbol19'), ('symbol36'), ('symbol54'), ('symbol13'), ('symbol90'), ('symbol115'), ('symbol145'), ('symbol165'), ('symbol12'))
order by symbol, date, created_time desc