Oracle SQL:未使用索引

Oracle SQL:未使用索引,sql,oracle,indexing,Sql,Oracle,Indexing,我有以下索引 create index i_payment_amount ON payment(amount); create index i_customer_createdate ON customer(createdate); 和下面的查询 select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney from customer c join rental r on c.customeri

我有以下索引

create index i_payment_amount ON payment(amount);
create index i_customer_createdate ON customer(createdate);
和下面的查询

select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney
from customer c
join rental r
on c.customerid = r.customerid
join payment p
on p.rentalid = r.rentalid
where  c.createdate > date '2019-06-01' + 30
or (select round(sum(pp.amount)) from payment pp
        join rental rr
        on rr.rentalid = pp.rentalid
        where rr.rentalid = r.rentalid) < 50 
group by c.firstname, c.lastname,c.createdate
order by c.firstname, c.lastname;

该查询将计算2019-06-01年之前一个月内注册的客户,以及花费不超过50美元的客户。我想借助索引对其进行优化

我创建了b-tree索引,第一次尝试时,我甚至想让索引出现在查询计划中,但没有

我也无法为付款创建基于函数的索引,因为它不支持组函数sum。 有没有建议创建一个适当的索引来优化查询,甚至使用它们?

包含HAVING子句会有什么好处?因为您已经有了所有这些值,所以可以完全避免子查询。大概是这样的:

SELECT c.createdate,
       c.firstname,
       c.lastname,
       ROUND (SUM (p.amount)) AS spentmoney
FROM customer c
         JOIN rental r ON c.customerid = r.customerid
         JOIN payment p ON p.rentalid = r.rentalid
GROUP BY c.firstname, c.lastname, c.createdate
HAVING SUM (p.amount) < 50
       OR c.createdate > DATE '2019-06-01' + 30
ORDER BY c.firstname, c.lastname;

我在查询中没有看到任何明显的索引候选项

假设customer中有200万行,其中100万行的createdate>date'2019-06-01'+30可以简化为createdate>date'2019-07-01'。使用索引查找这100万行,然后访问customer表100万次,这比只对表进行一次完全扫描要多得多。范围分区客户可能会有所帮助,前提是您获得了范围分区许可,具体取决于数据分布

可能是paymentrentalid上的一个索引,amount可以被Optimizer视为一个紧凑的表,它比paymentrentalid表本身更高效,因为这是表中唯一需要的两列,使得连接到paymentrentalid更高效。然而,这只是查询中涉及的三个表中的一个,所以我不希望有很大的改进

我注意到在你的问题中,你提到你想要2019-06-01前一个月注册的客户,但我在你的查询中没有看到这种情况。如果注册日期是c.createdate,那么可能

where  c.createdate > date '2019-06-01' + 30
应该更像

where  c.createdate between date '2019-06-01' and date '2019-07-01'

在这种情况下,c.createdate上的索引看起来更有用,但这是一个不同的查询。

任务是在执行时间超过2-3秒的情况下进行查询,这就是我创建子查询的原因。但现在的问题是关于索引。它们未被使用:@Undereamouse。问题是这是否会提高性能。但该指数并未出现。我想使用它们并比较前后的性能。即使它是否会提高性能?如果不使用索引,那么优化器认为不应该使用它。如果要强制执行,请使用提示。查询将计算2019-06-01之前一个月内注册的客户。您的查询没有这样做。就这一点而言,它也不会吸引花费不超过50美元的客户。它不会选择createdate>date'2019-06-01'+30或spentmoney<50的用户。如果没有,你有什么建议?但是,子查询应该保留,以使执行时间持续2-3秒。创建索引的想法是:创建索引i_payment_amount ON paymentroundamount,paymentid;之后,我将比较创建的索引的大小和手动创建的表的大小,并选择至少一个,但此索引也不用于查询计划。一、 首先,他无法尝试回答这个问题。我不知道您是否只是想加快您编写的查询的速度。或者,如果您希望高效地查询文本描述的内容。两者是不同的。