将平均值添加到平均值

时间:2014-11-17 03:11:26

标签: mysql math query-optimization

我有一个查询正在为现有平均值添加平均值,我缩短了为示例插入的行数,但通常我们每天多次执行5,000行。

INSERT INTO stats (impcount, 
                   average_position, 
                   state, 
                   dir_id, 
                   viz_id, 
                   date_date, 
                   org_id, 
                   order_id) VALUES  
('2', '1', '', '5537', '22189', '2014-11-06', '-1', '15963'), 
('2', '2', '', '5624', '22020', '2014-11-06', '-1', '15963'), 
('2', '3', '', '5624', '18215', '2014-11-06', '-1', '15963'), 
('2', '4', '', '6153', '22071', '2014-11-06', '-1', '15963'), 
('1', '9', '', '5624', '21735', '2014-11-06', '-1', '15634')  
ON DUPLICATE KEY UPDATE impcount = impcount + VALUES(impcount),  
average_position = VALUES(average_position) + ((((average_position * impcount) 
+  ( VALUES(impcount) * VALUES(average_position)) ) / (impcount  + VALUES(impcount) ))
- average_position);

表结构如下:

CREATE TABLE stats (
    record_id bigint(10) NOT NULL AUTO_INCREMENT,
    date_year varchar(4) DEFAULT NULL,
    date_month char(2) DEFAULT NULL,
    date_day char(2) DEFAULT NULL,
    impcount int(10) DEFAULT NULL,
    date_hour varchar(4) DEFAULT NULL,
    dir_id bigint(20) unsigned DEFAULT NULL,
    viz_id int(9) NOT NULL DEFAULT '0',
    order_id int(3) DEFAULT '0',
    date_date date NOT NULL DEFAULT '0000-00-00',
    average_position double DEFAULT NULL,
    state varchar(200) DEFAULT NULL,
    org_id int(10) unsigned DEFAULT NULL,
    PRIMARY KEY (record_id),
    UNIQUE KEY viz_id (viz_id,order_id,date_date,org_id),
    KEY viz_counts (viz_id,date_date,impcount,average_position,order_id),
    KEY daily_counts (date_date,impcount,order_id,average_position),
    KEY dir_counts (dir_id,date_date,order_id),
    KEY org_id (org_id)
) ENGINE=InnoDB AUTO_INCREMENT=33499742809 DEFAULT CHARSET=latin1;

有没有人知道如何简化这一点,我并不特别理解这背后的数学,但希望有人可能会认识到它,并且知道更好/更简单/更快的方法来完成同样的事情。

impcount是每行的展示次数,average_position是每次展示位置的直接平均值。根据我的理解,这是一个滚动平均值,其中每个重复密钥更新都保持平均值准确。

1 个答案:

答案 0 :(得分:0)

令A1和A2分别为计数N1和N2的两个平均值。然后是合并的平均值

    N1 × A1 + N2 × A2
A = -----------------
         N1 + N2

计数N = N1 + N2。


请注意,如果您将数据存储为 sums S1和S2并计算N1和N2,则执行此操作要容易得多。组合和为S1 + S2,组合计数为N1 + N2,平均值计算为S / N.