请您解释一下这两个是否在执行中有不同的表现。这两种方法几乎在同一时间内给出了几乎相同的结果,但我需要知道何时选择数百万个数据,哪个更合适。或者他们的执行逻辑是否相同?
select sum(case when equip = 'M' then cost end) material_total,
sum(case when equip = 'P' then cost end) personal_total,
sum(case when equip = 'T' then cost end) tool_facility_total,
sum(case when equip = 'X' then cost end) expense_total,
sum(case when equip = 'E' then cost end) external_total,
sum(case when equip = 'D' then cost end) direct_sales_total,
sum(cost) total
from exipmnt
where mch_code = mch_code_
and contract = contract_
and cre_date >= TO_DATE('01/01/' || year_, 'DD/MM/YYYY')
and cre_date < TO_DATE('01/01/' || year_, 'DD/MM/YYYY') + INTERVAL '1' YEAR
and equip in ('M', 'P', 'T', 'X', 'E', 'D');
2)
{{1}}
答案 0 :(得分:1)
你想知道什么是更好的:给定任务的PL / SQL或SQL。
PL / SQL是一种使用SQL的编程语言。因此,PL / SQL会将查询发送到SQL计算机并获取它为记录记录的结果。这是一个相当缓慢的过程。好的,PL / SQL和SQL引擎都在同一台机器上,因此没有开销很大,但仍然......
您的第二种方法显示该任务可以通过一个查询轻松解决。优化器将读取查询并找到最合适的执行方式。也许有一个索引可以帮助查找eqip代码,因此任务变得非常简单。或者优化器决定在几个并行任务中执行此操作以加快该过程。
你知道,DBMS在执行SQL时有很多可能的事情。简单地获取原始数据并从编程语言中评估它并不能利用这些可能性。因此,当您只能使用SQL执行相同的任务时,通常就是这样。 (虽然PL / SQL是一种很好的语言,可以使复杂的任务具有可读性,所以即使你可以为任务编写查询,你仍然可以为此决定PL / SQL。)
答案 1 :(得分:1)
嗨......我不太明白,为什么第一次查询是一种不好的做法。
做一个简单的实验,你会明白为什么这是一个不好的做法
做一个非常简单的查询(没有WHERE子句),一个在SQL中,另一个在PL / SQL中,对着一个有几十万行的表,并比较他们花了多长时间。
两个查询都只检索所有行表并计算结果。
以下是我在电脑上所做的事情:
创建测试表
create table EXIPMNT as
select column_value as equip,
trunc(dbms_random.value(0,100)) as cost
from table(DBMSOUTPUT_LINESARRAY('M','P','T','X'))
cross join
all_objects
;
select count(*) from EXIPMNT;
COUNT(*)
----------
294852
然后是最后一个查询(SQL)
set timing on
select sum(case when equip = 'M' then cost end) material_total,
sum(case when equip = 'P' then cost end) personal_total,
sum(case when equip = 'T' then cost end) tool_facility_total,
sum(case when equip = 'X' then cost end) expense_total,
sum(case when equip = 'E' then cost end) external_total,
sum(case when equip = 'D' then cost end) direct_sales_total,
sum(cost) total
from exipmnt;
Elapsed: 00:00:00.078
和第一个查询(PL / SQL)
set timing on
DECLARE
CURSOR get_cost_ IS
SELECT EQUIP, COST
FROM EXIPMNT;
material_ number;
personal_ number;
tool_facility_ number;
expense_ number;
external_ number;
direct_sales_ number;
BEGIN
FOR rec_ IN get_cost_ LOOP
IF (rec_. EQUIP = 'M') THEN
material_ := material_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'P') THEN
personal_ := personal_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'T') THEN
tool_facility_ := tool_facility_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'X') THEN
expense_ := expense_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'E') THEN
external_ := external_ + nvl(rec_.cost, 0);
ELSIF (rec_. EQUIP = 'D') THEN
direct_sales_ := direct_sales_ + nvl(rec_.cost, 0);
END IF;
NULL;
END LOOP;
end;
/
anonymous block completed
Elapsed: 00:00:03.265
现在检查结果(经过时间) - 3.265秒。 (PL / SQL)和0.078秒。 (SQL)
3.265 / 0.078 = 41,85 ,
这意味着,在这个简单的实验中, PL / SQL比简单的SQL慢约42倍。
这意味着差异是4200%!!!
由于上述PL / SQL被视为“不良做法”。