我有两个表:
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/