首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Postgres vs oracle做了100万sqrts,我做错了吗?

Postgres vs oracle做了100万sqrts,我做错了吗?
EN

Stack Overflow用户
提问于 2014-08-05 04:00:59
回答 8查看 2.1K关注 0票数 2

我们正在尝试了解Oracle与PostgreSQL的原始性能。我们有丰富的甲骨文经验,但对PostgreSQL来说还是个新手。我们将对我们的数据等运行大量查询,但首先我们想看看它们在基本内核任务上是如何执行的,即数学和分支,因为SQL就是建立在这些基础上的。

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

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

结果有点令人担忧:

代码语言:javascript
复制
Oracle      4.8 seconds

PostgreSQL  21.803 seconds

添加if语句:

代码语言:javascript
复制
Oracle      4.78 seconds

PostgreSQL  24.4 seconds

代码Oracle平方根

代码语言:javascript
复制
SET SERVEROUTPUT ON
SET TIMING ON

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

PostgreSQL

代码语言:javascript
复制
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

代码语言:javascript
复制
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;

postgres添加if

代码语言:javascript
复制
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使用了匿名块。我也把它当作一个函数来做,得到了相同的结果。

代码语言:javascript
复制
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的了解,以及它在许多方面与甲骨文的可比性,结果让我们大吃一惊。我们是否错误地编写了PostgreSQL代码?我们遗漏了什么,还是事情就是这样。

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

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

EN

回答 8

Stack Overflow用户

发布于 2014-08-05 18:03:18

正如其他人所说的,你的示例测试是毫无意义的。

我认为您遇到的基本问题是,您对PostgreSQL一无所知,并且在尝试与Oracle相同的基本技巧。

我们正在尝试了解Oracle与PostgreSQL的原始性能

好吧,这并不意味着什么,不是吗?除非您正在尝试测量原始磁盘读取或其他类似操作。

我们已经尽可能地调优了它们(检查了所有参数更改了随机页面成本,将seq扫描设置为off等)

好吧,将seq_scan设置为off不太可能是您想要做的事情,除非在探索测试用例时强制规划器。是什么让你这么做?它是在手册的什么地方建议的呢?您没有说明如何更改随机页面成本,也没有说明如何确定具有正确的值。

我们发现,使用PostgreSQL时,如果表大于共享内存设置的25%,则表数据不会被缓存。

好吧,这显然是不可能的。缓存发生在PostgreSQL和操作系统级别,并且磁盘数据块将被缓存。你如何衡量这一点?

(在我们的示例中,AWS30G实例的共享内存为7G,一旦我们的表大小低于2G,它就会再次开始缓存)

那么,如何调整shared_mem的大小呢?我正在尝试想象这样一种场景,2G和7G都是合理的值,但我遇到了麻烦。您没有提供任何内存使用信息,所以没有人能知道发生了什么。

我认为你需要做的是:

通过manuals.

  • Have获得一杯好的热茶/coffee.

  • Read通过维基例如Tuning Your PostgreSQL Server.

  • Once你可以合理地掌握

  • -mem和-mem是如何运行的在服务器上进行一些测量,这样你就可以看到内存使用情况,磁盘I/O等。
  1. 请确保您有一个关于如何将您的performance.

EXPLAIN ANALYZE到某个postgresql.org邮件列表的basic understanding (性能似乎是合理的),这样您就有了一个可以开始关注测量queries.

  • Subscribe的地方

在某些情况下,甲骨文将比PostgreSQL更聪明,但普遍的全面的主要减速并不是您所期望的。

票数 2
EN

Stack Overflow用户

发布于 2014-08-05 04:27:41

这只是一种猜测。我预计Oracle在这样的计算上会比Postgres慢。但是,我认为您的documentation中可能存在性能问题

类型numeric可以存储具有非常大的位数的数字,并准确地执行计算。特别推荐用于存储货币金额和其他需要精确度的数量。但是,与整数类型或下一节中描述的浮点类型相比,数值的算术非常慢。

您的代码没有为f声明数据类型。根据上下文,它将被指定为整数。但是,sqrt()函数接受浮点或numeric常量。这两种方法并不等价(我猜想当使用numeric时,函数会变慢)。我的猜测是,对于该操作,整数f被转换为number而不是real

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

票数 1
EN

Stack Overflow用户

发布于 2014-08-05 04:33:00

除非你碰巧用pl/sql或pg pl/sql做了大量的计算,否则我看不出这是一个有用的度量。无论如何都不推荐这样做,可以用C原生实现,也可以通过调用Java类实现。在某些平台/版本上,Oracle可以将pl/sql本机编译为c,因此这可能是您在速度上看到巨大差异的原因之一。

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

为了更好地描述和分析甲骨文,我建议查看https://asktom.oracle.com/论坛。我不确定postgres是否有类似的东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25126592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档