【问题标题】:Adding an average to an average将平均值添加到平均值
【发布时间】:2015-01-13 21:46:11
【问题描述】:

我有一个查询将平均值添加到现有平均值中,我已经缩短了示例中插入的行数,但通常我们每天多次执行 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 是每个展示位置的直接平均值。据我了解,这是一个滚动平均值,其中每个重复键更新都保持平均值准确。

【问题讨论】:

  • 如果可行,为什么需要更改它?
  • 它可以工作,但速度很慢,每天使用此查询不断更新大约 5000 行 - 我们还有其他数学较少的查询以相同的速度更新,没有任何问题。跨度>
  • 算术不太可能导致此查询的性能瓶颈。您可以编辑问题并添加表格定义吗?此外,也许在(大概)您想要数字的地方使用字符串常量可能会减慢查询速度。
  • 用表格结构更新问题
  • 需要更新2个key,这大概就是花时间的地方了。我不明白 VALUES(average_position) + 起始位和 `-average_position` 结束位(恕我直言,它们是错误,应该省略,除非我遗漏了什么),但正如 Gordon 所说: 你的时间不太可能花在哪里。其余的只是计算机的简单数学运算:如果 N 次平均 M,X 次平均 Y,则两者的平均值为 ((N*M) + (X*Y))/(M+Y)。为 MySQL 提供 integersdoubles 而不是 strings 如果这是它想要的,那么你可以赢得一些。

标签: mysql math query-optimization


【解决方案1】:

让 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。

【讨论】:

    猜你喜欢
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 2016-09-04
    • 2012-06-19
    相关资源
    最近更新 更多