如何解决加速字符串字段的连接
我有一个包含数据的表格,如下面的 tableA 示例。日期列的格式为字符串。
close 列是一个整数,ticker 格式为字符串。
我正在尝试在 mysql 数据库上运行下面的查询,这需要很长时间。
我可以做些什么来加快速度,例如更改日期列的格式或添加
索引或主键?代码和日期的组合应该是唯一值,日期字段是时间戳,目前只是格式化为字符串。
代码:
select avg((a.close-b.close)/b.close) as avg_annual_returns,a.ticker
from tableA a
join tableA b
on cast(a.date as date)=date_add(cast(b.date as date),interval 365 DAY)
and a.ticker=b.ticker
where b.close is not null
group by a.ticker
表A
+--------+-----+------+
|date |close|ticker|
+--------+-----+------+
|2/1/2019|5 |abc |
+--------+-----+------+
|2/3/2019|7 |efd |
+--------+-----+------+
|2/4/2019|3 |hij |
+--------+-----+------+
更新答案:
select ticker,date,( -1 +
a.close / max(a.close) over (partition by ticker
order by date
range between interval 365 day preceding and interval 365 day preceding
)
) as annual_returns
from tableA a
) b where annual_returns is not null
group by ticker
解决方法
如果你想要与一年前的不同,那么使用窗口函数。不过,在此之前,请修复数据模型!不要将日期存储为字符串。所以:
alter table talbeA modify column date date;
然后从一年前开始:
select( -1 +
a.close / max(a.close) over (partition by ticker
order by date
range between interval 365 day preceding and interval 365 day preceding
)
)
from tablea a;
您不必担心 NULL
值,因为 AVG()
会忽略它们。
Here 是一个 dbfiddle。
,问题出在这里:
on cast(a.date as date)=date_add(cast(b.date as date),interval 365 DAY)
它的两边都不是“sargeable”,所以它不能使用任何索引。
假设 date
是数据类型 DATE
,那么这有效:
ON a.date = b.date - INTERVAL 1 YEAR
还有
INDEX(ticker,date) -- in this order.
注意:1 YEAR
会在 2 月 28 日左右打嗝; 365 DAY
会每 4 年打嗝 366 天。
另外,改变
where b.close is not null
到
WHERE b.ticker IS NOT NULL
(功能上它们是相同的,但我在索引中选择了一列,以防万一。)好吧,有没有 close
为 NULL 的行?
哦,还有一个问题。因为周末,每周只有三四天能找到上一年的匹配日。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。