密集写入滚动窗口Postgresql数据库

密集写入滚动窗口Postgresql数据库,sql,postgresql,Sql,Postgresql,我有一个密集编写的数据库(50000行/分钟的连续流),其中几乎所有的值都一个接一个地插入到同一个表中。以前,我有一个带有一个表的常规数据库,但表越来越大,查询花费了太多时间 现在我已经设计了一个滚动窗口数据库。我有一个父表度量值和一组子表meas_1,meas_2…meas_7。在meas_1中,我插入今天的值,在meas_2中插入昨天的值,依此类推。当第二天到来时,我创建了一个新的meas_x子表,我删除了最旧的表meas_7,并设置了一个函数,该函数在我将数据插入测量值(父表)时触发,以便

我有一个密集编写的数据库(50000行/分钟的连续流),其中几乎所有的值都一个接一个地插入到同一个表中。以前,我有一个带有一个表的常规数据库,但表越来越大,查询花费了太多时间

现在我已经设计了一个滚动窗口数据库。我有一个父表度量值和一组子表meas_1,meas_2…meas_7。在meas_1中,我插入今天的值,在meas_2中插入昨天的值,依此类推。当第二天到来时,我创建了一个新的meas_x子表,我删除了最旧的表meas_7,并设置了一个函数,该函数在我将数据插入测量值(父表)时触发,以便将值重定向到meas_x(新的子表)。通过这样做,我可以在查询时利用CONTAINT_排除,也可以删除最旧的表(meas_7),而无需运行真空操作来释放光盘中的空间

触发器和函数如下所示:

CREATE TRIGGER insert_measurements_trigger 
                BEFORE INSERT ON measurements 
                FOR EACH ROW EXECUTE PROCEDURE measurements_insert_trigger();'


CREATE OR REPLACE FUNCTION measurements_insert_trigger() 
        RETURNS TRIGGER AS $$
        BEGIN
            IF ( NEW.timestamp >= d1_0 AND NEW.timestamp < d1_1 ) THEN
                INSERT INTO "meas_1" VALUES (NEW.*);
            ELSEIF ( NEW.timestamp >= d2_0 AND NEW.timestamp < d2_1 ) THEN 
                INSERT INTO "meas_2" VALUES (NEW.*); 
            ELSE 
                INSERT INTO "CatchLostRows" VALUES (NEW.*); 
            END IF; 
            RETURN NULL; 
        END; 
        $$ 
        LANGUAGE plpgsql;
创建触发器插入\u测量\u触发器
在插入测量值之前
对于每一行,执行过程测量_insert _trigger();'
创建或替换函数测量\u插入\u触发器()
将触发器返回为$$
开始
如果(NEW.timestamp>=d1\u 0和NEW.timestamp=d2_0和NEW.timestamp
请注意,d1_1>d1_0=d2_1>d2_0

我有一个Python脚本,负责更新滚动窗口数据库中的所有设置。我有另一个Python脚本负责插入所有数据


我的问题是,这个操作需要太多时间,我无法处理如此高的输入率。我一行一行地插入,因为函数是按行执行的,所以需要花费很多时间(这是我的客户机)。如何提高滚动数据库脚本的性能?还是制定一条规则更好

让Python决定应该插入哪个子级并不昂贵。我假设有7个孩子,每周一天一个

import psycopg2
from datetime import datetime
from psycopg2.extensions import AsIs

conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn")
cursor = conn.cursor()

insert_query = """
    insert into %(child)s (id, value, "timestamp")
    values
    (%(id)s, %(value)s, %(timestamp)s)
"""
timestamp = datetime(2014, 1, 1, 0, 0, 0)
insert_dict = {
    'child': AsIs('meas_' + str(timestamp.isoweekday())),
    'id': 1,
    'value': 1,
    'timestamp': timestamp
}

cursor.execute(insert_query, insert_dict)
conn.commit()

下一步是评估输入流的某种形式的缓存,以用于后续的大容量插入。数据来自哪里?如何操作?

您不能将Python脚本直接插入到子脚本中吗?这将避免触发,并可能允许有效的批量插入。如果没有更多细节,尤其是在Python插入脚本中,很难超越猜测。Python插入脚本执行以下操作:1)读取带有非格式化数据的字符串2)提取相关信息(id、值、时间戳)3)将相关信息(一次一行)插入表度量(父级)。我可以通过向子表插入数据来更改步骤3,但我会根据时间(检查时间戳)使用if语句。我认为用SQL编写这个if语句比用Python编写更高效/快速。首先感谢您的帮助。我已经删除了SQL触发器/函数,并且修改了insert Python脚本,以决定在哪个子表中插入新数据。到目前为止,它似乎运作良好。数据流以原始文本块的形式来自消息代理。我以一种产生多个插入的方式处理每个块(取决于块的大小)。由于现在的情况,我更方便地一个接一个地插入它们。如果在未来实验中插入延迟,我会考虑您的批量插入的建议。