效率比较

时间:2016-02-19 05:43:34

标签: sql oracle plsql

请您解释一下这两个是否在执行中有不同的表现。这两种方法几乎在同一时间内给出了几乎相同的结果,但我需要知道何时选择数百万个数据,哪个更合适。或者他们的执行逻辑是否相同?

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}}

2 个答案:

答案 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被视为“不良做法”。