我不太了解sql来改进数据库查询。
我有以下本机sql查询:
SELECT
m.id,
m.merchantname,
date_trunc('month' ,to_timestamp(t.timestamp / 1000)) as month_name,
COUNT(*) as num_transactions,
cast(SUM(case when t.type IN('VEND_READER','VEND_READER_COUPON_TRANSFER') THEN t.amount ELSE 0 END) as numeric) AS sum_vend,
cast(SUM(case when t.type IN('REVALUE_READER','REVALUE_STARTBALANCE','REVALUE_PAYPAL','REVALUE_PROMOTION','REVALUE_CREDITCARD') THEN t.amount ELSE 0 END) AS numeric) as sum_revalue
FROM
transaction t JOIN merchant m ON m.id = t.merchant_id
WHERE
t.transactionstate = 'SUCCESS'
GROUP BY
m.id, month_name
ORDER BY
m.id
我想要的只是参赛作品,包括每个商家和月份的一揽子/重估和交易次数。
如何格式化月字段(可能是sql时间戳或字符串或......)
[
{merchantID:1, merchantName:"myMerchant", vend:2030, revalue:1980, transactions:115, month:"July - 2016"},
{merchantID:1, merchantName:"myMerchant", vend:1895, revalue:2700, transactions:100, month:"June - 2016"},
{merchantID:1, merchantName:"myMerchant", vend:2453, revalue:1892, transactions:120, month:"May - 2016"},
{merchantID:2, merchantName:"myMerchant2", vend:345, revalue:360, transactions:123, month:"July - 2016"},
...
]
如果使用JPA可以进行这样的查询,那就太棒了。但我找不到将毫秒级的纪元时间转换为一个月的方法。我们所有的时间戳(自1970年以来的毫秒数)都保存为BIGINT。
Merchant.java
@Entity
public class Merchant
{
@Id
@GeneratedValue
private Long id;
private Integer merchantGlobalID;
private String merchantName;
}
Transaction.java
@Entity
public class Transaction
{
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Merchant merchant;
private Integer amount;
private Long timestamp;
@Enumerated(EnumType.STRING)
private TransactionType type;
@Enumerated(EnumType.STRING)
private TransactionState transactionState;
}
我的查询有效,但性能非常糟糕。我们使用postgres数据库,当前查询使用一些特定的命令。如果有办法在JPA中获得结果,那就太好了。
修改
根据Robe Elckers的建议,我调用EXPLAIN ANALYZE
查询。结果如下。我不知道我现在该做什么。
GroupAggregate (cost=797050.04..849223.46 rows=1070224 width=559) (actual time=6913.003..7368.277 rows=16 loops=1)
Group Key: m.id, (date_trunc('month'::text, to_timestamp(((t."timestamp" / 1000))::double precision)))
-> Sort (cost=797050.04..799725.60 rows=1070224 width=559) (actual time=6792.567..7049.720 rows=1070341 loops=1)
Sort Key: m.id, (date_trunc('month'::text, to_timestamp(((t."timestamp" / 1000))::double precision)))
Sort Method: external merge Disk: 57384kB
-> Hash Join (cost=4.61..155797.88 rows=1070224 width=559) (actual time=0.104..6005.352 rows=1070341 loops=1)
Hash Cond: (t.merchant_id = m.id)
-> Seq Scan on transaction t (cost=0.00..130375.45 rows=1070224 width=32) (actual time=0.006..3502.850 rows=1070341 loops=1)
Filter: ((transactionstate)::text = 'SUCCESS'::text)
Rows Removed by Filter: 1598
-> Hash (cost=4.27..4.27 rows=27 width=535) (actual time=0.023..0.023 rows=27 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 2kB
-> Seq Scan on merchant m (cost=0.00..4.27 rows=27 width=535) (actual time=0.004..0.015 rows=27 loops=1)
Planning time: 0.535 ms
Execution time: 7373.833 ms