【发布时间】:2015-06-27 17:00:08
【问题描述】:
我有一个相当简单的数据库模型。我的“主”表如下所示:
| id (PK) | device_id (int) | msg_type (int) | rawdata (text) | timestamp (date+time) |
因此,每个接收到的消息都存储在此表中,包括消息类型、时间戳、发送它的设备和原始数据。
除了每个可能的 msg_type(总共大约 30 个)之外,我还有一个单独的表来存储已解析的原始数据。表“main_type1”的示例:
| id (PK) | main_id (FK) | device_id (int) | attribute_1 | attribute_2 | attribute_n |
(每个 msg_type 的结构不同,消息分布不均,这意味着有些表很长,有些表很小)。
请注意,device_id 始终包含在 rawdata 中,因此每个表都有此列。
现在是我的问题:
我曾经有过这样的查询:
select attribute_1, attribute_2 from main_type1 inner join main on main_type1.main_id = main.id where timestamp > X and timestamp < Y and main.device_id = Z
一开始一切都足够而且很快。但是现在我的数据库在“main”中有超过 400.000.000 个条目。现在查询最多需要 15 分钟。
索引
我尝试使用索引,例如:
CREATE INDEX device_id_index ON main (device_id);
好吧,现在我可以更快地从主表中检索数据,但它对连接没有帮助。我最大的问题是我只将时间戳信息存储在主表中。所以我必须一直加入......这是我的数据库模型的一般故障吗?我试图避免两次存储时间戳。
分区
一种解决方案是使用分区为每个 device_id 创建一个包含原始数据的新表吗?然后我会(当然自动)创建适当的分区,例如:
main_device_id_343223
main_device_id_4563
main_device_id_92338
main_device_id_4142315
这会给我与连接相关的速度优势吗?我还有什么其他选择?为了完整起见:我使用的是 PostgreSQL
【问题讨论】:
-
分区不是查询性能特性,与使用良好的索引策略相比,它通常会使查询性能更差。
-
当您的查询根本没有提到设备时,为什么要在设备上编制索引?
-
@usr:你说得对,我在查询中添加了缺少的 id。当然,我正在尝试获取特定设备的数据。感谢您指出这一点!
-
您是否尝试过为这个特定查询创建理想的索引?每张桌子上一个。报告该配置的性能数。
-
“完美索引”是什么意思?说明有点不清楚,你能给我更多关于我应该使用哪些索引的信息吗?然后我会报告绩效率
标签: database performance postgresql indexing partitioning