我做了一个简单的整数更新性能测试.SQLite每秒只更新15次,而PostgreSQL每秒更新1500次.

SQLite case 的数字似乎是normal.

SQLite站点中的FAQ解释了旋转磁盘的基本限制.

实际上,SQLite可以轻松地在每个数据库中执行50000条或更多INSERT语句

默认情况下,每个INSERT语句都是自己的事务.但如果你

另一个选项是运行PRAGMA synchronous=OFF.这个命令将

这是真的吗?那么,PostgreSQL怎么能比SQLite执行得更快呢?

更新:

以下是用Clojure编写的完整测试代码:

(defproject foo "0.1.0-SNAPSHOT"
  :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.clojure/java.jdbc "0.3.0-SNAPSHOT"]
                 [com.mchange/c3p0 "0.9.2.1"]
                 [org.xerial/sqlite-jdbc "3.7.2"]
                 [postgresql "9.1-901.jdbc4"]])
(ns foo.core
  (:require [clojure.java.jdbc :as jdbc]
            [clojure.java.jdbc.ddl :as ddl])
  (:import  [com.mchange.v2.c3p0 ComboPooledDataSource]))

(def sqlite
  (let [spec {:classname "org.sqlite.JDBC"
              :subprotocol "sqlite"
              :subname "test.db"}]
    {:datasource (doto (ComboPooledDataSource.)
                   (.setDriverClass (:classname spec))
                   (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
                   (.setMaxIdleTimeExcessConnections (* 30 60))
                   (.setMaxIdleTime (* 3 60 60)))}))

(def postgres
  (let [spec {:classname "org.postgresql.Driver"
              :subprotocol "postgresql"
              :subname "//localhost:5432/testdb"
              :user "postgres"
              :password "uiop"}]
    {:datasource (doto (ComboPooledDataSource.)
                   (.setDriverClass (:classname spec))
                   (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
                   (.setUser (:user spec))
                   (.setPassword (:password spec))
                   (.setMaxIdleTimeExcessConnections (* 30 60))
                   (.setMaxIdleTime (* 3 60 60)))}))

(doseq [x [sqlite postgres]]
  (jdbc/db-do-commands x
    (ddl/create-table :foo [:id :int "PRIMARY KEY"] [:bar :int])))

(doseq [x [sqlite postgres]]
  (jdbc/insert! x :foo {:id 1 :bar 1}))

(defmacro bench
  [expr n]
  `(dotimes [_# 3]
     (let [start# (. System (nanoTime))]
       (dotimes [_# ~n]
         ~expr)
       (let [end#               (. System (nanoTime))
             elapsed#           (/ (double (- end# start#)) 1000000.0)
             operation-per-sec# (long (/ (double ~n) (/ (double (- end# start#)) 1000000000)))]
       (prn (str "Elapsed time: " elapsed# " ms (" (format "%,d" operation-per-sec#) " ops)"))))))

(bench (jdbc/query sqlite ["select * from foo"]) 20000)
(bench (jdbc/execute! sqlite ["update foo set bar=bar+1 where id=?" 1]) 100)

(bench (jdbc/query postgres ["select * from foo"]) 20000)
(bench (jdbc/execute! postgres ["update foo set bar=bar+1 where id=?" 1]) 5000)

结果是:

; Running "select * from foo" 20000 times in SQLite

"Elapsed time: 1802.426963 ms (11,096 ops)"
"Elapsed time: 1731.118831 ms (11,553 ops)"
"Elapsed time: 1749.842658 ms (11,429 ops)"

; Running "update foo set bar=bar+1 where id=1" 100 times in SQLite

"Elapsed time: 6362.829057 ms (15 ops)"
"Elapsed time: 6405.25075 ms (15 ops)"
"Elapsed time: 6352.943553 ms (15 ops)"

; Running "select * from foo" 20000 times in PostgreSQL

"Elapsed time: 2898.636079 ms (6,899 ops)"
"Elapsed time: 2824.77372 ms (7,080 ops)"
"Elapsed time: 2837.622659 ms (7,048 ops)"

; Running "update foo set bar=bar+1 where id=1" 5000 times in PostgreSQL

"Elapsed time: 3213.120219 ms (1,556 ops)"
"Elapsed time: 3564.249492 ms (1,402 ops)"
"Elapsed time: 3280.128708 ms (1,524 ops)"

pg_fsync_测试结果:

C:\temp>"C:\Program Files\PostgreSQL\9.3\bin\pg_test_fsync"
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   81199.920 ops/sec      12 usecs/op
        fdatasync                                     n/a
        fsync                              45.337 ops/sec   22057 usecs/op
        fsync_writethrough                 46.470 ops/sec   21519 usecs/op
        open_sync                                     n/a

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   41093.981 ops/sec      24 usecs/op
        fdatasync                                     n/a
        fsync                              38.569 ops/sec   25927 usecs/op
        fsync_writethrough                 36.970 ops/sec   27049 usecs/op
        open_sync                                     n/a

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write                     n/a
         2 *  8kB open_sync writes                    n/a
         4 *  4kB open_sync writes                    n/a
         8 *  2kB open_sync writes                    n/a
        16 *  1kB open_sync writes                    n/a

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close                45.564 ops/sec   21947 usecs/op
        write, close, fsync                33.373 ops/sec   29964 usecs/op

Non-Sync'ed 8kB writes:
        write                             889.800 ops/sec    1124 usecs/op

推荐答案

你猜疑是对的.具有您指定的设置的PostgreSQL不应能够在每秒对旋转介质的单独连续事务中执行接近1500次的更新.

你的IO堆栈中可能有关于如何实现同步的谎言或错误.这意味着您的数据在意外断电或操作系统故障后有严重损坏的风险.

从pg_test_fsync的结果来看,情况的确如此.open_datasync是Windows下的默认设置,它的速度似乎不切实际,因此肯定不安全.当我在Windows7机器上运行pg_test_fsync时,我看到了同样的情况.

Postgresql相关问答推荐

Redis作为postgreSQL嵌套数据的缓存

PostgreSQL数据文件是否仅在判断点期间写入磁盘?

在PostgreSQL中,`MY_VARIABLE IN(<;Long_ARRAY_of_Items>;)`何时是FAST?

仅使用 ssl 连接到 Postgresql 数据库

在Postgres游标中从一行变量中减go 另一行变量

postgres 中的模式前缀,被调用元素的范围

如何将 NULL 值插入 UUID 而不是零

PostgreSQL:如何避免被零除?

有对(type_id,element_id),如(1,1),(1,2),..(5,3).如果我需要获取没有 element_id 1 的类型 ID,如何从结果中排除 type_id?

无法从在 wsl 2 上运行的服务之一连接到在 wsl 2 上的容器中运行的 postgres 数据库

我可以在 Ruby on Rails 上编写 PostgreSQL 函数吗?

postgres 的密码

计算 PostgreSQL 中给定 GPS 坐标的日出和日落时间

如何在容器内创建 postgres 扩展?

Postgis 中 2 点之间的距离,单位为 4326 米

如何判断 PostgreSQL 事务中的待处理操作

Entity Framework Core jsonb 列类型

如何在 postgresql 中获取整个表的哈希?

如何在 JPA 中使用 Postgres JSONB 数据类型?

pgadmin 错误:no password supplied