mysql - 慢子查询: group by a groupwise maximum

标签 mysql query-optimization query-performance

我有两个表:

CREATE TABLE share_prices (
    price_id int(10) unsigned NOT NULL AUTO_INCREMENT,
    price_date date NOT NULL,
    company_id int(10) NOT NULL,
    high decimal(20,2) DEFAULT NULL,
    low decimal(20,2) DEFAULT NULL,
    close decimal(20,2) DEFAULT NULL,
    PRIMARY KEY (price_id),
    UNIQUE KEY price_date (price_date,company_id),
    KEY company_id (company_id),
    KEY price_date_2 (price_date)
) ENGINE=InnoDB AUTO_INCREMENT=368586 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

还有

CREATE TABLE rating_lookup (
    rating_id int(11) NOT NULL,
    start_date date DEFAULT NULL,
    start_price decimal(10,2) DEFAULT NULL,
    broker_id int(11) DEFAULT NULL,
    company_id int(11) DEFAULT NULL,
    end_date date DEFAULT NULL,
    PRIMARY KEY (rating_id),
    KEY idx_rating_lookup_company_id (company_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这是当前查询:

SELECT broker_id, count(rating_id)

FROM (

    SELECT rating_lookup.*,
    share_prices.company_id as correct_company,
    share_prices.price_date,
    max(high) as peak_gain,
    ( ( ( max(high) - rating_lookup.start_price ) / rating_lookup.start_price ) * 100 ) as percent_gain

    FROM rating_lookup, share_prices

    WHERE share_prices.price_date > rating_lookup.start_date 
    AND share_prices.price_date < ifnull(end_date, curdate())
    AND share_prices.company_id = rating_lookup.company_id

    GROUP BY rating_id

    HAVING percent_gain > 5

) correct

GROUP BY broker_id

目前此查询需要10.969秒

独立子查询需要0.391秒(持续时间)/10.438秒(获取)

查询目标:

获取每个broker_id的正确评级总数。

正确评级的定义是自 start_price 起已达到 + 5% 的评级。


我希望大幅减少查询时间,即使重组数据库是唯一的方法。


附录

解释上述查询:

+---+---------+---------------+-------+--------------------------------------+------------+---+----------------------------------------+---------+---------------------------------+
| 1 | PRIMARY | <derived2>    | ALL   |                                      |            |   |                                        | 3894800 | Using temporary; Using filesort |
| 2 | DERIVED | rating_lookup | index | PRIMARY,idx_rating_lookup_company_id | PRIMARY    | 4 |                                        |   18200 | Using where                     |
| 2 | DERIVED | share_prices  | ref   | price_date,company_id,price_date_2   | company_id | 4 | brokermetrics.rating_lookup.company_id |     214 | Using where                     |
+---+---------+---------------+-------+--------------------------------------+------------+---+----------------------------------------+---------+---------------------------------+

share_prices ~ 375,000 行

rating_lookup ~ 18,000 行,约有 46 个唯一经纪人

最佳答案

我假设股票价格每天在市场收盘后插入一次(如果您覆盖多个市场,则每天插入几次)。

如果您无法充分调整查询,则可以预先计算结果。每次加载完一批新股票价格后运行查询。将结果插入新表中。读取预先计算的数据应该足够快。

关于mysql - 慢子查询: group by a groupwise maximum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45218172/

相关文章:

mysql - 从第一个单词中获取 3 个字母,从下一个单词中获取 3 个字母

使用 group by 的 MySQL 查询性能问题

重复时 MySQL 查询运行速度变慢

mysql - MySQL View 的优化

sql-server - SQL Server基于值分布的优化查询

sql-server - 为什么使用 Table Spool 比不使用慢?

mysql - 查询 'across'数据透视表

mysql - 如何正确(加入if)MySQL查询?

php - 使用 Laravel 使用自定义变量更新语句

mysql - 如何优化这个简单的 JOIN+ORDER BY 查询?