Oracle SQL 分区范围全部而不是范围单一
Oracle SQL Partition range all instead of range single
我按日期创建了一个分区 table,我在其中划分了创建日期(当客户创建帐户时)。
CREATE TABLE PARTITIONED_customer (
customerId number(10) GENERATED AS IDENTITY,
firstName varchar2(50),
lastName varchar2(50),
email varchar2(50),
createDate date,
active char(1),
PRIMARY KEY (customerId))
PARTITION BY RANGE (createDate)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION first_quater_2018 VALUES LESS THAN(TO_DATE('01-04-2018','dd-MM-yyyy')),
PARTITION second_quater_2018 VALUES LESS THAN(TO_DATE('01-07-2018','dd-MM-yyyy')),
PARTITION third_quater_2018 VALUES LESS THAN(TO_DATE('01-10-2018','dd-MM-yyyy')),
PARTITION fourth_quater_2018 VALUES LESS THAN(TO_DATE('01-01-2019','dd-MM-yyyy')),
PARTITION first_quater_2019 VALUES LESS THAN(TO_DATE('01-04-2019','dd-MM-yyyy')),
PARTITION second_quater_2019 VALUES LESS THAN(TO_DATE('01-07-2019','dd-MM-yyyy')),
PARTITION third_quater_2019 VALUES LESS THAN(TO_DATE('01-10-2019','dd-MM-yyyy')),
PARTITION fourth_quater_2019 VALUES LESS THAN(TO_DATE('01-01-2020','dd-MM-yyyy')));
这是 SQL 查询,我想在其中了解客户创建帐户的时间。我知道查询不完全正确,提前表示歉意
select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney
from PARTITIONED_customer c
join PARTITIONED_rental r
on c.customerid = r.customerid
join PARTITIONED_payment_amount p
on p.rentalid = r.rentalid
where c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy')
AND TO_DATE('01-06-2019','dd-MM-yyyy')
or (select round(sum(pp.amount)) from PARTITIONED_payment_amount pp
join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
group by c.firstname, c.lastname,c.createdate
order by c.firstname, c.lastname;
Explainer 显示分区范围全部,而不是单个。如何解决?
我用简单的查询自己检查了分区,没有问题。所以,我认为查询本身有问题。
您的查询正在 PARTITIONED_CUSTOMER 上执行 TABLE ACCESS FULL,因此它当然必须搜索所有分区。我建议在分区键上创建索引:
CREATE INDEX PARTITIONED_CUSTOMER_1
ON PARTITIONED_CUSTOMER (CREATEDATE)
LOCAL;
如果您确实需要,可以在查询中指定一个 PARTITION 子句:
select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney
from PARTITIONED_customer PARTITION (second_quater_2019) c
INNER join PARTITIONED_rental r
on c.customerid = r.customerid
INNER join PARTITIONED_payment_amount p
on p.rentalid = r.rentalid
where c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
TO_DATE('01-06-2019','dd-MM-yyyy') or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
group by c.firstname, c.lastname,c.createdate
order by c.firstname, c.lastname
此外 - 您在此查询中有 AND
和 OR
条件未完全括起来。 AND
和 OR
的计算顺序可能与您认为的不同。你是说
(c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
TO_DATE('01-06-2019','dd-MM-yyyy')) or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
或者你是说
c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
(TO_DATE('01-06-2019','dd-MM-yyyy') or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50)
如果您像这样混合使用 AND
和 OR
,最好使用括号根据需要对操作进行分组,否则您可能得不到预期的结果。
我按日期创建了一个分区 table,我在其中划分了创建日期(当客户创建帐户时)。
CREATE TABLE PARTITIONED_customer (
customerId number(10) GENERATED AS IDENTITY,
firstName varchar2(50),
lastName varchar2(50),
email varchar2(50),
createDate date,
active char(1),
PRIMARY KEY (customerId))
PARTITION BY RANGE (createDate)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION first_quater_2018 VALUES LESS THAN(TO_DATE('01-04-2018','dd-MM-yyyy')),
PARTITION second_quater_2018 VALUES LESS THAN(TO_DATE('01-07-2018','dd-MM-yyyy')),
PARTITION third_quater_2018 VALUES LESS THAN(TO_DATE('01-10-2018','dd-MM-yyyy')),
PARTITION fourth_quater_2018 VALUES LESS THAN(TO_DATE('01-01-2019','dd-MM-yyyy')),
PARTITION first_quater_2019 VALUES LESS THAN(TO_DATE('01-04-2019','dd-MM-yyyy')),
PARTITION second_quater_2019 VALUES LESS THAN(TO_DATE('01-07-2019','dd-MM-yyyy')),
PARTITION third_quater_2019 VALUES LESS THAN(TO_DATE('01-10-2019','dd-MM-yyyy')),
PARTITION fourth_quater_2019 VALUES LESS THAN(TO_DATE('01-01-2020','dd-MM-yyyy')));
这是 SQL 查询,我想在其中了解客户创建帐户的时间。我知道查询不完全正确,提前表示歉意
select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney
from PARTITIONED_customer c
join PARTITIONED_rental r
on c.customerid = r.customerid
join PARTITIONED_payment_amount p
on p.rentalid = r.rentalid
where c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy')
AND TO_DATE('01-06-2019','dd-MM-yyyy')
or (select round(sum(pp.amount)) from PARTITIONED_payment_amount pp
join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
group by c.firstname, c.lastname,c.createdate
order by c.firstname, c.lastname;
我用简单的查询自己检查了分区,没有问题。所以,我认为查询本身有问题。
您的查询正在 PARTITIONED_CUSTOMER 上执行 TABLE ACCESS FULL,因此它当然必须搜索所有分区。我建议在分区键上创建索引:
CREATE INDEX PARTITIONED_CUSTOMER_1
ON PARTITIONED_CUSTOMER (CREATEDATE)
LOCAL;
如果您确实需要,可以在查询中指定一个 PARTITION 子句:
select c.createdate, c.firstname, c.lastname, round(sum(p.amount)) as spentmoney
from PARTITIONED_customer PARTITION (second_quater_2019) c
INNER join PARTITIONED_rental r
on c.customerid = r.customerid
INNER join PARTITIONED_payment_amount p
on p.rentalid = r.rentalid
where c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
TO_DATE('01-06-2019','dd-MM-yyyy') or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
group by c.firstname, c.lastname,c.createdate
order by c.firstname, c.lastname
此外 - 您在此查询中有 AND
和 OR
条件未完全括起来。 AND
和 OR
的计算顺序可能与您认为的不同。你是说
(c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
TO_DATE('01-06-2019','dd-MM-yyyy')) or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50
或者你是说
c.createdate BETWEEN TO_DATE('01-05-2019','dd-MM-yyyy') AND
(TO_DATE('01-06-2019','dd-MM-yyyy') or
(select round(sum(pp.amount))
from PARTITIONED_payment_amount pp
INNER join PARTITIONED_rental rr
on rr.rentalid = pp.rentalid
where rr.customerid=c.customerid) < 50)
如果您像这样混合使用 AND
和 OR
,最好使用括号根据需要对操作进行分组,否则您可能得不到预期的结果。