我有类似的查询,我需要查找特定客户在一个时间范围内的交易数量:
select customer_id, count(transactions)
from transactions
where customer_id = 'FKJ90838485'
and purchase_date between '01-JAN-13' and '31-AUG-13'
group by customer_id
表事务未在customer_id上编制索引,而是另一个名为transaction_id的字段。 Customer_ID是字符类型,而transaction_id是数字。
'accounting_month'字段也被编入索引..此字段仅存储交易发生的月份...即,purchase_date = '03 -MAR-13'将具有accounting_month = '01 -MAR-13'
交易表在'01 -JAN-13'和'31 -AUG-13'的时间范围内有大约2000万条记录
当我运行上述查询时,它需要超过40分钟才能回来,有任何想法或提示吗?
答案 0 :(得分:4)
正如其他人已经评论过的那样,最好是添加一个覆盖查询的索引,所以:
(customer_id, purchase_date)
上添加索引,因为查询正在执行表扫描。图片的标题说明:
您不必将customer_id
放在SELECT
列表中,如果从那里删除它,也可以从GROUP BY
删除它,以便查询变为:
select count(*) as number_of_transactions
from transactions
where customer_id = 'FKJ90838485'
and purchase_date between DATE '2013-01-01' and DATE '2013-08-31' ;
如果您在WHERE
上没有customer_id
条件,则可以在GROUP BY
和SELECT
列表中创建select customer_id, count(*) as number_of_transactions
from transactions
where purchase_date between DATE '2013-01-01' and DATE '2013-08-31'
group by customer_id ;
条件将计算每个客户的交易数量。以上建议的指数也有助于此:
{{1}}
答案 1 :(得分:0)
这只是我想到的一个想法。它可能会起作用,尝试运行它,看看它是否比你现有的有所改进。
我正在尽可能地使用你所说的transaction_id
索引。
WITH min_transaction (tran_id)
AS (
SELECT MIN(transaction_ID)
FROM TRANSACTIONS
WHERE
CUSTOMER_ID = 'FKJ90838485'
AND purchase_date >= '01-JAN-13'
), max_transaction (tran_id)
AS (
SELECT MAX(transaction_ID)
FROM TRANSACTIONS
WHERE
CUSTOMER_ID = 'FKJ90838485'
AND purchase_date <= '31-AUG-13'
)
SELECT customer_id, count(transaction_id)
FROM transactions
WHERE
transaction_id BETWEEN min_transaction.tran_id AND max_transaction.tran_id
GROUP BY customer_ID
答案 2 :(得分:0)
这可能会更快,因为它会查看范围的transaction_id
而不是purchase_date
。我还考虑到accounting_month
被编入索引:
select customer_id, count(*)
from transactions
where customer_id = 'FKJ90838485'
and transaction_id between (select min(transaction_id)
from transactions
where accounting_month = '01-JAN-13'
) and
(select max(transaction_id)
from transactions
where accounting_month = '01-AUG-13'
)
group by customer_id
也许你也可以尝试:
select customer_id, count(*)
from transactions
where customer_id = 'FKJ90838485'
and accounting_month between '01-JAN-13' and '01-AUG-13'
group by customer_id