Sql Postgres vs oracle完成100万平方米我做错了吗?

Sql Postgres vs oracle完成100万平方米我做错了吗?,sql,database,oracle,postgresql,amazon-web-services,Sql,Database,Oracle,Postgresql,Amazon Web Services,我们试图了解Oracle与PostgreSQL的原始性能。我们拥有丰富的oracle经验,但对PostgreSQL来说是新手。我们将使用数据等运行大量查询,但首先我们想看看它们在基本内核任务上的执行情况,即数学和分支,因为SQL是建立在这些任务上的 在AWS RDS中,我们创建了两个db.m3.2x大型实例,一个包含oracle 11.2.0.4.v1许可证,另一个包含PostgreSQL(9.3.3) 在这两种情况下,我们都运行了100万平方根的代码(从1百万到1百万)。然后在If..Then

我们试图了解Oracle与PostgreSQL的原始性能。我们拥有丰富的oracle经验,但对PostgreSQL来说是新手。我们将使用数据等运行大量查询,但首先我们想看看它们在基本内核任务上的执行情况,即数学和分支,因为SQL是建立在这些任务上的

在AWS RDS中,我们创建了两个db.m3.2x大型实例,一个包含oracle 11.2.0.4.v1许可证,另一个包含PostgreSQL(9.3.3)

在这两种情况下,我们都运行了100万平方根的代码(从1百万到1百万)。然后在If..Then语句中执行相同的操作

结果有点令人不安:

Oracle      4.8 seconds

PostgreSQL  21.803 seconds
添加if语句:

Oracle      4.78 seconds

PostgreSQL  24.4 seconds
代码 甲骨文平方根

SET SERVEROUTPUT ON
SET TIMING ON

DECLARE
  n NUMBER := 0;
BEGIN
  FOR f IN 1..10000000
LOOP
    n := SQRT (f);
  END LOOP;
END;
PostgreSQL

DO LANGUAGE plpgsql $$ DECLARE n real;
BEGIN
FOR f IN 1..10000000 LOOP
n = SQRT (f);
END LOOP;
RAISE NOTICE 'Result => %',n;
END $$;
oracle添加if

SET SERVEROUTPUT ON
SET TIMING ON

DECLARE
  n NUMBER := 0;
BEGIN
  FOR f IN 1..10000000
LOOP
  if 0 =0 then
    n := SQRT (f);
    end if;
  END LOOP;
博士后加if

DO LANGUAGE plpgsql $$ DECLARE n real;
BEGIN
FOR f IN 1..10000000 LOOP
if 0=0 then 
n = SQRT (f);
end if;
END LOOP;
RAISE NOTICE 'Result => %',n;
END $$;
我为PostgreSQL使用了一个匿名块。我也把它作为一个函数,得到了相同的结果

CREATE OR REPLACE FUNCTION testpostgrescpu()
  RETURNS real AS
$BODY$
declare
     n real;
BEGIN
   FOR f IN 1..10000000 LOOP        
    n = SQRT (f);       
   END LOOP;        


   RETURN n;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION testpostgrescpu()
  OWNER TO xxx
根据我们对PostgreSQL的了解以及它在许多方面与Oracle的可比性,我们对结果感到震惊。我们是否错误地编写了PostgreSQL?我们错过了什么,或者就是这样

注意:当我们开始在Oracle和PostgreSQL中对完全相同的数据运行查询时,我们看到了类似的模式。在基本的查询上差别不大,但随着它们开始变得越来越复杂,Oracle大约快了3-5个


同样,这是在相同的AWS RDS实例上运行的,我们在一天中的不同日期多次运行它们,结果总是相同的

这是一种推测。我预计甲骨文在这种计算上会比博士后慢。但是,我认为您可能存在以下性能问题:

numeric类型可以存储具有大量数字的数字 并精确地进行计算。特别推荐用于以下情况: 在需要精确性的地方存储货币数量和其他数量 必修的。然而,相比之下,数值运算速度非常慢 中描述的整数类型或浮点类型 下一节

您的代码没有为
f
声明数据类型。根据上下文,它将被指定为整数。但是,
sqrt()
函数采用浮点或
数值
常量。这些都是不等价的(我猜当一个
数字时,函数会变慢)。我猜整数
f
会被转换为
数字
,而不是
实数


尝试通过显式地将
f
声明为
real
或在函数调用之前强制转换来运行测试。这可能会提高性能。

除非您碰巧在pl/sql或pg pl/sql中进行了大量计算,否则我看不出这是一个多么有用的指标。无论如何,这并不是真正推荐的方法,它可以在C中本机完成,也可以通过调用Java类来完成。Oracle可以在某些平台/版本上将pl/sql本机编译为c,因此这可能是您看到速度差异很大的原因之一

数据库的速度更好地取决于它执行查询(可能包括具有正确统计信息的联接)或写入和更新数据的能力。对于Oracle和Postgres sql这样的数据库,假设您有一个OLTP应用程序,那么在多用户和事务性环境中执行此操作将是一个更好的测试。据我所知,Postgres在与Oracle的竞争中表现不错,但这取决于您的应用程序


为了更好地描述和分析Oracle,我建议查看asktom论坛。我不确定博士后是否有类似的情况。

老实说,你的基准测试毫无意义

你在计算一百万个平方根,然后马上扔掉结果;根据您的优化设置,我希望编译器完全摆脱您的循环

您至少应该将结果存储在某个地方,或者将其用于另一次计算(例如,通过计算总和)


另外,我不得不不同意你的说法,即数学和分支,因为SQL是建立在这一点上的。RDBMS可以做很多事情,但是有效地计算平方根肯定不是它的优点之一。如果你真的,真的需要这种计算,将其从数据库中移出,并使用某种专门的软件,例如R,会更有意义

我对这些基准有点惊讶,但我倾向于在概念上同意弗兰克·施密特的观点。虽然我不会说这是“完全没有意义的”,但如果你要比较两个DBMS系统,我想你应该考虑的不仅仅是每个DBMS系统是如何计算的

不管它值多少钱,我几乎只在我以前的雇主那里使用甲骨文。在我的新角色中,我们的主要DBMS是Sybase ASE,它缺少许多我已经习惯使用的工具,我们使用PostgreSQL作为权宜之计

毫无疑问,有比我将要提供的更好的评论,但从新手的角度来看:

我怀念Oracle的东西:

  • 操作系统身份验证(允许用户根据其Windows/Unix凭据登录的能力),没有混乱的密码问题
  • “合并”语句
  • 通过OCI(ODP.net,DBD::Oracle)进行批量插入和更新
  • 通过过程部分提交的能力
  • 优秀IDE的可用性(如全方位自动化PL/SQL开发人员)
  • 位图索引
  • 更无缝的数据库链接
我喜欢PostgreSQL的一些方面:

  • 价格标签
  • “复制”比SQL*加载器更容易使用
  • ODBC和.NET的Npgsql.dll等驱动程序的可用性
  • SQL内部的自定义函数不会降低查询性能
  • 能够用PL(即Perl)以外的语言创建自定义函数
  • 更容易
    select * from pg_views
    where definition like '%inventory.turns%'
    
    DO LANGUAGE plpgsql $$
    DECLARE n real;
    BEGIN
        FOR f IN 1..10000000 LOOP
            n = f::float;
        END LOOP;
        RAISE NOTICE 'Result => %',n;
    END $$;
    
    DO LANGUAGE plpgsql $$
    DECLARE n float;
    BEGIN
        FOR f IN 1..10000000 LOOP
            n = f::float;
        END LOOP;
        RAISE NOTICE 'Result => %',n;
    END $$;