0

我有一个与此类似的查询,我需要在其中找到特定客户在某个时间范围内的交易数量:

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

表 transactions 没有在 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 多分钟才回来,有什么想法或提示吗?

4

3 回答 3

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条件 on customer_id,您可以将它放在GROUP BYSELECT列表中以编写一个查询,该查询将计算每个客户的交易数量。上述建议的索引也将对此有所帮助:

    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  ;
    
于 2013-09-05T17:39:18.783 回答
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
于 2013-09-05T16:09:25.500 回答
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
于 2013-09-05T16:38:30.060 回答