【发布时间】:2021-07-30 11:57:04
【问题描述】:
我有一个查询,它返回按帐户分组的时间间隔内的买入、卖出和转账的总和,问题是它很慢,我只在过去 24 小时内进行交易,我想能够为所有交易运行此功能(2 年内 800,000 次)。我该如何优化它?
select
i.interval, ca.contract_address,
coalesce(SUM(t.amount) FILTER (WHERE t.action = 0), 0) as amount_ampl_bought,
coalesce(SUM(t.amount) FILTER (WHERE t.action = 1), 0) as amount_ampl_sold,
coalesce(SUM(t.amount) FILTER (WHERE t.action = 2), 0) as amount_ampl_transferred,
coalesce(SUM(t.supply_percentage) FILTER (WHERE t.action = 0), 0) as percent_ampl_bought,
coalesce(SUM(t.supply_percentage) FILTER (WHERE t.action = 1), 0) as percent_ampl_sold,
coalesce(SUM(t.supply_percentage) FILTER (WHERE t.action = 2), 0) as percent_ampl_transferred
from
(
select contract_address
from addresses a
where not exists (select 1 from address_tags at where at.address = a.contract_address and at.tag_id = 3)
) ca
cross join
(
SELECT date_trunc('hour', dd) as interval
FROM generate_series
(
(now() at time zone 'utc') - interval '1 day',
(now() at time zone 'utc'),
'1 hour'::interval
) dd
) i
left join transfers t on (t.from = ca.contract_address or t.to = ca.contract_address) and date_trunc('hour', t.timestamp at time zone 'utc') = i.interval
group by i.interval, ca.contract_address;
示例输出:
interval | contract_address | amount_ampl_bought | amount_ampl_sold | amount_ampl_transferred | percent_ampl_bought | percent_ampl_sold | percent_ampl_transferred
---------------------+--------------------------------------------+--------------------+------------------+-------------------------+-----------------------------+----------------------------+----------------------------
2021-05-08 11:00:00 | 0x0000000000000000000000000000000000000000 | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x000000000000000000000000000000000000dead | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x000000000000006f6502b7f2bbac8c30a3f67e9a | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x000000000000084e91743124a982076c59f10084 | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x0000000000000eb4ec62758aae93400b3e5f7f18 | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x00000000000017c75025d397b91d284bbe8fc7f2 | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x0000000000005117dd3a72e64a705198753fdd54 | 0 | 0 | 0 | 0 | 0 | 0
2021-05-08 11:00:00 | 0x000000000000740a22fa209cf6806d38f7605385 | 0 | 0 | 0 | 0 | 0 | 0
链接到可视化查询:
https://explain.depesz.com/s/SrLf
我在转账时创建的索引:
CREATE INDEX transfers_from_to_index ON public.transfers USING btree ("from", "to")
CREATE INDEX transfers_timestamp_index ON public.transfers USING btree ("timestamp")
CREATE INDEX transfers_action_index ON public.transfers USING btree (action)
CREATE UNIQUE INDEX transfers_pkey ON public.transfers USING btree (transaction_hash, log_index)
CREATE INDEX transfers_supply_percentage_index ON public.transfers USING btree (supply_percentage)
CREATE INDEX transfers_amount_index ON public.transfers USING btree (amount)
CREATE INDEX transfers_supply_percentage_timestamp_log_index_index ON public.transfers USING btree (supply_percentage, "timestamp", log_index)
CREATE INDEX transfers_date_trunc_idx ON public.transfers USING btree (date_trunc('hour'::text, timezone('utc'::text, "timestamp")))
CREATE INDEX transfers_to_index ON public.transfers USING btree ("to")
我在地址上创建的索引:
CREATE UNIQUE INDEX addresses_pkey ON public.addresses USING btree (contract_address)
CREATE INDEX addresses_supply_percentage_index ON public.addresses USING btree (supply_percentage)
非常感谢您对此优化的帮助!
【问题讨论】:
-
如果您限定了 all 列引用,这会有所帮助,以便清楚列的来源。
-
感谢您的反馈,我现在就去做!
-
如果从加入中删除 LEFT 需要多长时间?也许只获取存在的数据并通过不同的机制填充缺失值会更快。
标签: sql postgresql performance optimization query-optimization