簡體   English   中英

Oracle SQL:未使用索引

[英]Oracle SQL: Indexes not being used

我有以下索引

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 索引,第一次嘗試時,我什至想讓索引出現在查詢計划中,但他們沒有。

我也無法為付款創建基於函數的索引,因為它不支持組 function (sum)。 是否有任何建議來創建適當的索引,以優化查詢甚至使用它們?

我在查詢中沒有看到任何明顯的索引候選者。

假設customer中有 200 萬行,其中有 100 萬行createdate > date '2019-06-01' + 30 (可以簡化為createdate > date '2019-07-01' )。 使用索引查找這 100 萬行,然后訪問customer表一百萬次,這將比僅對表進行一次全掃描要多得多的 I/O。 如果您獲得許可並且取決於數據分布,范圍分區customer可能會有所幫助。

優化器可能payment(rentalid, amount)上的索引視為一個瘦表,這將比payment表本身更有效地進行全掃描,因為它們是表中唯一需要的兩列,使得加入payment更高效。 但是,這只是查詢中涉及的三個表之一,所以我不希望有很大的改進。

我注意到您在問題中提到您想要在 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上的索引開始看起來更有用,但這是一個不同的查詢。

包含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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM