postgresql - 如何在 Postgres 中正确索引和查询时间序列数据?
问题描述
我最近正在尝试使用 Postgres 而不是使用 Bigquery。
我的表transactions_all
结构
access_id (text)
serial_no (text)
transaction_id (text)
date_local (timestamp)
和index (BTREE, condition (((date_local)::date), serial_no))
当我将一个月的 500.000 行加载到该表中时,像这样查询最近 2 天的性能还可以
SELECT *
FROM transactions_all
WHERE DATE(date_local) BETWEEN CURRENT_DATE - INTERVAL '1 day' AND CURRENT_DATE
AND access_id = 'accessid1'
and serial_no = 'IO99267637'
但是如果我选择像这样的过去 21 天
SELECT *
FROM transactions_all
WHERE DATE(date_local) BETWEEN CURRENT_DATE - INTERVAL '20 day' AND CURRENT_DATE
AND access_id = 'accessid1'
and serial_no = 'IO99267637'
然后获取数据需要几秒钟而不是几毫秒。
这是正常行为还是我使用了错误的索引?
解决方案
您的索引列的顺序错误。=
在前面,您需要与条件中的运算符一起使用的那些表达式WHERE
,因为不能再使用与不同运算符一起使用的列之后的索引列。
为了理解这一点,想象一个电话簿,其中的名字是按(姓氏,名字)排序的。然后考虑很容易找到姓“Miller”和名字小于“J”的所有条目:您只需阅读“Miller”条目,直到您点击“J”。现在考虑任务是查找所有“Joe”的全名小于“M”:您必须扫描直到“M”的所有条目,并且对名字也进行排序对您没有多大帮助.
所以使用像这样的索引
CREATE INDEX ON transactions_all (serial_no, access_id, date(date_local));
推荐阅读
- jquery - 切换事件忽略 if($(window).height() > 800){
- python - 使用 if 语句打印函数
- javascript - 检查日期是否在时间范围内
- wordpress - 如何删除我的 wordpress 网站顶部的空白
- c - 为什么我的 while() 语句陷入无限循环?
- css - 在小型设备中,如何使用 bootstrap4 将顶部 div 放在底部,底部 div 放在顶部?
- ffmpeg - 使用ffmpeg复制时如何排除eia_608字幕?
- java - Akka如何连接source、flow和sink
- 32bit-64bit - 在 WebAssembly 中同时拥有 32 位和 64 位数字的基本原理是什么?
- ruby-on-rails - 录像机磁带导轨