我有一个表,里面有58k条交易记录。我只想带回在date参数(通常是1天)中有3笔已拒绝付款的payment\u ref(客户id)。付款是尝试一天三次,只要其中一个是授权的,我很高兴。这是我一天中要追上的三次衰退。我现在的问题是
SELECT DISTINCT(cp.payment_ref) as ref
, (SELECT COUNT(id)
FROM client_payments
WHERE status LIKE 'Declined'
AND payment_ref = ref) as declined
FROM client_payments as cp
WHERE cp.payment_date BETWEEN '2018-05-14 00:00:00' AND '2018-05-14 23:59:59'
但是查询要花很长时间,计数超过3(嵌入式查询似乎在整个表上搜索),我在所有搜索字段上都有索引。这张table摆成follows:-
name , payment_ref, timestamp , status
smith, 123 , 2018-05-15 10:12:22, Declined
smith, 123 , 2018-05-15 14:12:22, Declined
smith, 123 , 2018-05-15 19:12:22, Declined
john , 246 , 2018-05-15 10:12:22, Declined
john , 246 , 2018-05-15 14:12:22, Authorised (OK, 2nd payment is auth'd)
jones, 135 , 2018-05-15 10:00:22, Authorised (OK, 1st payment is auth'd)
我哪里出错了?
4条答案
按热度按时间laawzig21#
似乎只有count子查询中才需要时间范围。
为什么不把where语句移到子查询中呢?这将大大减少运行时间:
zkure5ic2#
谢谢你的回复。最快运行的查询如下.08秒
SELECT cp.payment_ref as ref,count(status='Declined') as no_declined FROM client_payments as cp WHERE cp.payment_date BETWEEN '2018-05-14 00:00:00' AND '2018-05-14 23:59:59' GROUP BY cp.payment_ref HAVING COUNT(status='Declined')>2
b4qexyjb3#
我发现不需要依赖子查询来获取计数,您可以从主查询中获取它,并为所需的计数去掉distinct use聚合
还要检查是否使用了查询和搜索键/索引的解释计划
oewdyzsn4#
在确定你有索引之后
payment_ref
,timestamp
以及status
,我会用自连接来解决它:这使得索引得到最佳利用,并且通过关键范围扫描具有非常高的选择性
如果您真的需要逐行表单,可以通过只运行一次的 Package 器查询对其进行转换。