[英]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.