为什么PostgreSQL比MongoDB还快之完结篇(深挖单点索引查询)
生活随笔
收集整理的這篇文章主要介紹了
为什么PostgreSQL比MongoDB还快之完结篇(深挖单点索引查询)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
之前兩篇測試中發(fā)現(xiàn):單點(diǎn)索引查詢中PostgreSQL的速度是MongoDB(WiredTiger引擎)的4倍。
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=20726500&id=4960138
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=20726500&id=4981629
雖然本人很偏好PG,但也對這個(gè)結(jié)果表示不能理解。按照常理,純NoSQL的MongoDB應(yīng)該比PG快或和PG差不多快才比較合理。
所以,在之前測試的基礎(chǔ)上再進(jìn)行一次深入的挖掘。
之前的0匹配查詢,由于執(zhí)行的時(shí)間太短,沒有采集到CPU利用率,而且時(shí)間值太小,對比的準(zhǔn)確性也值得懷疑。
所以,現(xiàn)在構(gòu)造一個(gè)循環(huán)的單點(diǎn)索引查詢,并在單并發(fā)和多并發(fā)場景下對比PG和MongoDB的性能。
1. MongoDB(WiredTiger引擎)的測試
單并發(fā)測試
循環(huán)1萬次單點(diǎn)索引查詢,平均一次大約返回一條記錄。
-bash-4.1$ cat batchselect_mongo.sh
???for ((i=0;i${1};i++))
???do
???????echo "db.json_tables.find({ brand: 'ACME${i}'})"
???done
-bash-4.1$ sh batchselect_mongo.sh 10000|time -p mongo benchmark >/dev/null
real 8.53
user 4.59
sys 2.62
-bash-4.1$ sh batchselect_mongo.sh 10000|time -p mongo benchmark|grep ACME|wc
real 8.33
user 5.33
sys 1.51
???9091 3281851 22061914
看看top的資源使用
[root@hanode1 bin]# top top - 08:29:13 up 11 days, 11:29, 6 users, load average: 0.09, 0.03, 0.01 Tasks: 159 total, 2 running, 157 sleeping, 0 stopped, 0 zombie Cpu(s): 16.8%us, 1.3%sy, 0.0%ni, 75.6%id, 0.0%wa, 0.0%hi, 6.4%si, 0.0%st Mem: 1019320k total, 942260k used, 77060k free, 134736k buffers Swap: 2064376k total, 64712k used, 1999664k free, 265524k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3951 postgres 20 0 746m 63m 9200 R 85.5 6.4 0:06.97 mongo 26391 postgres 20 0 617m 339m 12m S 19.3 34.1 10:01.76 mongod
算下來mongod進(jìn)程占用CPU 1.6s(8.33*19.3%=1.6)
3并發(fā)的測試
前面一直是單并發(fā)測試,現(xiàn)在看看3并發(fā)的場景(測試機(jī)是4核)。
-bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [1] 5398 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [2] 5401 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [3] 5412 -bash-4.1$ real 8.61 user 6.30 sys 0.64 real 8.61 user 6.37 sys 0.59 real 8.49 user 6.36 sys 0.62 [1] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [2]- Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [3]+ Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null
3并發(fā)時(shí)的top結(jié)果
[root@hanode1 bin]# top top - 08:42:13 up 11 days, 11:42, 6 users, load average: 1.26, 0.95, 0.39 Tasks: 166 total, 4 running, 162 sleeping, 0 stopped, 0 zombie Cpu(s): 67.4%us, 5.3%sy, 0.0%ni, 25.0%id, 0.0%wa, 0.0%hi, 2.3%si, 0.0%st Mem: 1019320k total, 570600k used, 448720k free, 1008k buffers Swap: 2064376k total, 136636k used, 1927740k free, 38632k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5399 postgres 20 0 746m 63m 9192 R 82.5 6.3 0:05.27 mongo 5402 postgres 20 0 744m 61m 9192 R 82.5 6.1 0:05.27 mongo 5413 postgres 20 0 744m 61m 9192 R 82.1 6.2 0:04.96 mongo 26391 postgres 20 0 625m 266m 3048 S 47.5 26.8 10:27.54 mongod
可以注意到幾點(diǎn)
1)每個(gè)客戶端的執(zhí)行時(shí)間和單并發(fā)時(shí)差不多一樣。3個(gè)mongo進(jìn)程和1個(gè)mongod進(jìn)程幾乎各占了一個(gè)CPU核,沒有CPU爭用。
2)mongod進(jìn)程的CPU實(shí)際占用時(shí)間是8.6*47.5%=4s,是單并發(fā)時(shí)的2.5倍(接近理論效果的3倍,里面會有測量誤差)
3)性能瓶頸還是在客戶端
10并發(fā)的測試
10并發(fā)時(shí),忙碌的進(jìn)程數(shù)超過CPU核心數(shù),會有CPU爭用。
-bash-4.1$ -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [1] 5156 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [2] 5159 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [3] 5161 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [4] 5163 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [5] 5166 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [6] 5170 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [7] 5172 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [8] 5174 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [9] 5177 -bash-4.1$ sh batchselect_mongo.sh 10000 |time -p mongo benchmark >/dev/null & [10] 5179 -bash-4.1$ -bash-4.1$ real 25.15 user 7.97 sys 1.06 real 25.54 user 7.93 sys 1.02 real 26.32 user 7.94 sys 1.08 real 26.63 user 8.39 sys 0.93 real 27.01 user 8.44 sys 1.04 real 28.06 user 8.52 sys 1.02 real 28.16 user 8.11 sys 1.24 real 28.27 user 8.47 sys 1.03 real 28.64 user 8.23 sys 1.13 real 29.14 user 8.11 sys 1.12 [1] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [2] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [3] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [4] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [5] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [6] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [7] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [8] Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [9]- Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null [10]+ Done sh batchselect_mongo.sh 10000 | time -p mongo benchmark > /dev/null
10并發(fā)時(shí)的top結(jié)果
[root@hanode1 bin]# top top - 08:40:22 up 11 days, 11:40, 6 users, load average: 1.60, 0.40, 0.14 Tasks: 187 total, 11 running, 176 sleeping, 0 stopped, 0 zombie Cpu(s): 73.7%us, 24.9%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 1.5%si, 0.0%st Mem: 1019320k total, 969800k used, 49520k free, 77180k buffers Swap: 2064376k total, 66948k used, 1997428k free, 36160k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 26391 postgres 20 0 625m 332m 5220 S 50.5 33.4 10:10.47 mongod 5168 postgres 20 0 745m 50m 9200 R 40.5 5.0 0:02.16 mongo 5175 postgres 20 0 745m 58m 9192 R 40.5 5.9 0:02.19 mongo 5167 postgres 20 0 745m 48m 9192 R 34.9 4.9 0:01.97 mongo 5157 postgres 20 0 745m 48m 9192 R 34.6 4.8 0:01.96 mongo 5184 postgres 20 0 744m 44m 9192 R 34.6 4.5 0:01.68 mongo 5164 postgres 20 0 744m 44m 9192 R 33.6 4.5 0:01.67 mongo 5182 postgres 20 0 744m 44m 9192 R 31.2 4.5 0:01.58 mongo 5180 postgres 20 0 744m 44m 9192 R 30.9 4.5 0:01.58 mongo 5181 postgres 20 0 744m 44m 9192 R 29.2 4.5 0:01.52 mongo 5183 postgres 20 0 744m 44m 9192 R 28.6 4.5 0:01.54 mongo
1)mongod進(jìn)程的CPU實(shí)際占用時(shí)間大約是27*50.5%=13.5s,是單并發(fā)時(shí)的8.4倍(接近理論效果的10倍,里面會有測量誤差)
2)CPU被撐滿,客戶端消耗的大部分的CPU資源。
循環(huán)1萬次單點(diǎn)索引查詢,平均一次大約返回一條記錄。
-bash-4.1$ cat batchselect_pg.sh for ((i=0;i do echo "SELECT data FROM json_tables WHERE data @> '{\"brand\":\"ACME${i}\"}';" done -bash-4.1$ sh batchselect_pg.sh 10000|time -p psql -qAt benchmark >/dev/null real 1.48 user 0.13 sys 0.14
由于PG太快了,不好收集top信息,改成10萬次循環(huán)。
-bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null real 10.72 user 0.96 sys 1.01 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark |wc real 10.91 user 0.61 sys 1.49 9091 3172759 21561900
看看top結(jié)果
[root@hanode1 bin]# top top - 09:18:00 up 11 days, 12:18, 6 users, load average: 0.35, 0.14, 0.05 Tasks: 166 total, 2 running, 164 sleeping, 0 stopped, 0 zombie Cpu(s): 27.5%us, 4.5%sy, 0.0%ni, 67.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1019320k total, 349168k used, 670152k free, 9200k buffers Swap: 2064376k total, 68376k used, 1996000k free, 243836k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9042 postgres 20 0 587m 77m 76m R 81.8 7.8 0:04.35 postgres 9038 postgres 20 0 103m 1224 1064 S 31.9 0.1 0:01.60 sh 9041 postgres 20 0 105m 1204 1016 S 18.6 0.1 0:01.08 psql 算下來postgres進(jìn)程占用CPU 8.9s(10.9*81.1%=8.9)。也就是說mongod進(jìn)程的CPU實(shí)際占用時(shí)間是postgres進(jìn)程的1.8倍,而不是之前簡單測試得出的4倍。
3并發(fā)的測試
點(diǎn)擊(此處)折疊或打開
-bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [1] 9740 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [2] 9743 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [3] 9746 -bash-4.1$ -bash-4.1$ -bash-4.1$ real 14.15 user 1.21 sys 1.03 real 14.34 user 1.20 sys 1.01 real 14.41 user 1.23 sys 1.01 [1] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [2]- Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [3]+ Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null
top的結(jié)果
[root@hanode1 bin]# top top - 09:25:01 up 11 days, 12:25, 6 users, load average: 0.97, 0.24, 0.08 Tasks: 176 total, 4 running, 172 sleeping, 0 stopped, 0 zombie Cpu(s): 68.6%us, 13.3%sy, 0.0%ni, 18.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1019320k total, 354280k used, 665040k free, 9512k buffers Swap: 2064376k total, 68376k used, 1996000k free, 243848k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9749 postgres 20 0 587m 77m 76m R 70.2 7.8 0:08.37 postgres 9750 postgres 20 0 587m 77m 76m R 67.5 7.8 0:08.60 postgres 9748 postgres 20 0 587m 77m 76m R 65.8 7.8 0:08.44 postgres 9739 postgres 20 0 103m 1224 1064 S 31.9 0.1 0:03.39 sh 9745 postgres 20 0 103m 1224 1064 S 28.9 0.1 0:03.35 sh 9742 postgres 20 0 103m 1228 1064 S 25.3 0.1 0:03.32 sh 9741 postgres 20 0 105m 1200 1016 S 16.3 0.1 0:01.95 psql 9744 postgres 20 0 105m 1200 1016 S 15.6 0.1 0:02.01 psql 9747 postgres 20 0 105m 1200 1016 S 15.6 0.1 0:01.95 psql
算下來postgres進(jìn)程占用CPU 大約28.3s(14*(70%+67%+65%+)=28.3),是單并發(fā)時(shí)的3.2倍。
10并發(fā)的測試
點(diǎn)擊(此處)折疊或打開 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [1] 10628 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [2] 10631 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [3] 10634 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [4] 10637 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [5] 10639 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [6] 10641 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [7] 10644 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [8] 10646 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [9] 10648 -bash-4.1$ sh batchselect_pg.sh 100000|time -p psql -qAt benchmark >/dev/null & [10] 10651 -bash-4.1$ -bash-4.1$ -bash-4.1$ real 38.35 user 1.47 sys 0.85 real 38.72 user 1.39 sys 0.90 real 38.87 user 1.45 sys 0.91 real 39.13 user 1.50 sys 0.82 real 39.23 user 1.41 sys 0.94 real 39.63 user 1.42 sys 0.93 real 39.75 user 1.39 sys 0.90 real 39.84 user 1.36 sys 0.98 real 40.24 user 1.42 sys 0.92 real 40.58 user 1.40 sys 0.93 [1] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [2] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [3] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [4] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [5] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [6] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [7] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [8] Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [9]- Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null [10]+ Done sh batchselect_pg.sh 100000 | time -p psql -qAt benchmark > /dev/null
10并發(fā)時(shí)的top結(jié)果
[root@hanode1 bin]# top top - 09:34:12 up 11 days, 12:34, 6 users, load average: 5.21, 1.33, 0.47 Tasks: 201 total, 12 running, 189 sleeping, 0 stopped, 0 zombie Cpu(s): 84.7%us, 14.9%sy, 0.0%ni, 0.3%id, 0.0%wa, 0.0%hi, 0.1%si, 0.0%st Mem: 1019320k total, 370468k used, 648852k free, 9952k buffers Swap: 2064376k total, 68376k used, 1996000k free, 243860k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10664 postgres 20 0 587m 77m 76m R 26.8 7.8 0:08.77 postgres 10660 postgres 20 0 587m 77m 76m R 26.2 7.8 0:08.83 postgres 10665 postgres 20 0 587m 77m 76m R 26.2 7.8 0:08.46 postgres 10642 postgres 20 0 587m 77m 76m R 25.5 7.8 0:08.48 postgres 10656 postgres 20 0 587m 77m 76m R 25.5 7.8 0:08.15 postgres 10663 postgres 20 0 587m 77m 76m R 24.8 7.8 0:08.48 postgres 10662 postgres 20 0 587m 77m 76m R 23.8 7.8 0:08.73 postgres 10635 postgres 20 0 587m 77m 76m R 23.5 7.8 0:09.20 postgres 10666 postgres 20 0 587m 77m 76m R 23.5 7.8 0:08.87 postgres 10654 postgres 20 0 587m 77m 76m R 22.5 7.8 0:07.94 postgres 10636 postgres 20 0 103m 1224 1064 S 9.9 0.1 0:03.15 sh 10638 postgres 20 0 103m 1228 1064 S 9.9 0.1 0:03.08 sh 10650 postgres 20 0 103m 1228 1064 S 9.6 0.1 0:03.18 sh 10627 postgres 20 0 103m 1228 1064 S 9.3 0.1 0:03.00 sh 10640 postgres 20 0 103m 1228 1064 R 9.3 0.1 0:02.84 sh 10645 postgres 20 0 103m 1224 1064 S 9.3 0.1 0:03.14 sh 10630 postgres 20 0 103m 1228 1064 S 8.6 0.1 0:03.22 sh 10633 postgres 20 0 103m 1228 1064 S 8.6 0.1 0:02.98 sh 10647 postgres 20 0 103m 1228 1064 S 8.6 0.1 0:03.17 sh 10643 postgres 20 0 103m 1228 1064 S 8.3 0.1 0:02.82 sh 10658 postgres 20 0 105m 1200 1016 S 7.0 0.1 0:02.05 psql 10655 postgres 20 0 105m 1200 1016 S 6.6 0.1 0:02.09 psql 10629 postgres 20 0 105m 1200 1016 S 6.3 0.1 0:02.02 psql 10657 postgres 20 0 105m 1200 1016 S 6.3 0.1 0:01.93 psql 10652 postgres 20 0 105m 1204 1016 S 6.0 0.1 0:01.88 psql 10649 postgres 20 0 105m 1204 1016 S 5.6 0.1 0:01.84 psql 10659 postgres 20 0 105m 1200 1016 S 5.6 0.1 0:01.97 psql 10632 postgres 20 0 105m 1204 1016 S 5.3 0.1 0:02.09 psql 10653 postgres 20 0 105m 1204 1016 S 5.3 0.1 0:01.96 psql 10661 postgres 20 0 105m 1200 1016 S 5.3 0.1 0:02.04 psql
1)大致算下來postgres進(jìn)程占用CPU 大約97.5s(39*25%*10=97.5),是單并發(fā)時(shí)的10.9倍(97.5/8.9)。
2)CPU被撐滿,postgres進(jìn)程占用了大部分的CPU。
從上面的結(jié)果可以看出:
1)在多并發(fā)場景下,MongoDB和PostgreSQL的服務(wù)端進(jìn)程占用的總CPU時(shí)間和并發(fā)數(shù)基本成正比。說明負(fù)載在CPU多核間分擔(dān)的比較好。
2)多并發(fā)時(shí)MongoDB在單點(diǎn)索引查詢占用的CPU時(shí)間大約是PostgreSQL的1.4倍。
3)這個(gè)1.4倍的比率基本可以代表了實(shí)際場景(高并發(fā),且客戶端和服務(wù)端不在同一臺機(jī)器上)下它們的單點(diǎn)索引查詢性能差異,而不是之前簡單測試顯示的4倍。
經(jīng)過這樣嚴(yán)格的比較,我終于可以相信PostgreSQL在單點(diǎn)索引查詢上比MongoDB(WiredTiger引擎)快了那么一點(diǎn)點(diǎn)。
結(jié)合前兩次測試結(jié)果,最終的總結(jié)如下
1)加載
? WiredTiger的性能是PG的3倍(注1,注2)
2)插入
?相差不大,WiredTiger小勝(注1,注2)
3)全表掃描(0匹配)
?WiredTiger的性能是PG的4倍
4)單點(diǎn)索引掃描
?PG的性能是WiredTiger的1.4倍(注1)
5)數(shù)據(jù)大小
?PG的數(shù)據(jù)大小是WiredTiger的3倍
注1)以服務(wù)端進(jìn)程CPU消耗作為衡量指標(biāo)的,忽略了MongoDB客戶端的高CPU消耗。
注2)僅僅是單并發(fā)的測試數(shù)據(jù)
這個(gè)結(jié)果雖然和開頭那個(gè)EnterpriseDB的流傳較廣的測試結(jié)果有很大出入,但PG的NoSQL特性在單機(jī)環(huán)境下仍然有巨大的優(yōu)勢(即:NoSQL+SQL+ACID)。
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=20726500&id=4960138
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=20726500&id=4981629
雖然本人很偏好PG,但也對這個(gè)結(jié)果表示不能理解。按照常理,純NoSQL的MongoDB應(yīng)該比PG快或和PG差不多快才比較合理。
所以,在之前測試的基礎(chǔ)上再進(jìn)行一次深入的挖掘。
之前的0匹配查詢,由于執(zhí)行的時(shí)間太短,沒有采集到CPU利用率,而且時(shí)間值太小,對比的準(zhǔn)確性也值得懷疑。
所以,現(xiàn)在構(gòu)造一個(gè)循環(huán)的單點(diǎn)索引查詢,并在單并發(fā)和多并發(fā)場景下對比PG和MongoDB的性能。
1. MongoDB(WiredTiger引擎)的測試
單并發(fā)測試循環(huán)1萬次單點(diǎn)索引查詢,平均一次大約返回一條記錄。
點(diǎn)擊(此處)折疊或打開
看看top的資源使用
點(diǎn)擊(此處)折疊或打開
算下來mongod進(jìn)程占用CPU 1.6s(8.33*19.3%=1.6)
3并發(fā)的測試
前面一直是單并發(fā)測試,現(xiàn)在看看3并發(fā)的場景(測試機(jī)是4核)。
點(diǎn)擊(此處)折疊或打開
3并發(fā)時(shí)的top結(jié)果
點(diǎn)擊(此處)折疊或打開
可以注意到幾點(diǎn)
1)每個(gè)客戶端的執(zhí)行時(shí)間和單并發(fā)時(shí)差不多一樣。3個(gè)mongo進(jìn)程和1個(gè)mongod進(jìn)程幾乎各占了一個(gè)CPU核,沒有CPU爭用。
2)mongod進(jìn)程的CPU實(shí)際占用時(shí)間是8.6*47.5%=4s,是單并發(fā)時(shí)的2.5倍(接近理論效果的3倍,里面會有測量誤差)
3)性能瓶頸還是在客戶端
10并發(fā)的測試
10并發(fā)時(shí),忙碌的進(jìn)程數(shù)超過CPU核心數(shù),會有CPU爭用。
點(diǎn)擊(此處)折疊或打開
10并發(fā)時(shí)的top結(jié)果
點(diǎn)擊(此處)折疊或打開
1)mongod進(jìn)程的CPU實(shí)際占用時(shí)間大約是27*50.5%=13.5s,是單并發(fā)時(shí)的8.4倍(接近理論效果的10倍,里面會有測量誤差)
2)CPU被撐滿,客戶端消耗的大部分的CPU資源。
2. PostgreSQL的測試
單并發(fā)測試循環(huán)1萬次單點(diǎn)索引查詢,平均一次大約返回一條記錄。
點(diǎn)擊(此處)折疊或打開
由于PG太快了,不好收集top信息,改成10萬次循環(huán)。
點(diǎn)擊(此處)折疊或打開
看看top結(jié)果
點(diǎn)擊(此處)折疊或打開
3并發(fā)的測試
點(diǎn)擊(此處)折疊或打開
top的結(jié)果
點(diǎn)擊(此處)折疊或打開
算下來postgres進(jìn)程占用CPU 大約28.3s(14*(70%+67%+65%+)=28.3),是單并發(fā)時(shí)的3.2倍。
10并發(fā)的測試
點(diǎn)擊(此處)折疊或打開
10并發(fā)時(shí)的top結(jié)果
點(diǎn)擊(此處)折疊或打開
1)大致算下來postgres進(jìn)程占用CPU 大約97.5s(39*25%*10=97.5),是單并發(fā)時(shí)的10.9倍(97.5/8.9)。
2)CPU被撐滿,postgres進(jìn)程占用了大部分的CPU。
3.總結(jié)
測試結(jié)果總結(jié)如下從上面的結(jié)果可以看出:
1)在多并發(fā)場景下,MongoDB和PostgreSQL的服務(wù)端進(jìn)程占用的總CPU時(shí)間和并發(fā)數(shù)基本成正比。說明負(fù)載在CPU多核間分擔(dān)的比較好。
2)多并發(fā)時(shí)MongoDB在單點(diǎn)索引查詢占用的CPU時(shí)間大約是PostgreSQL的1.4倍。
3)這個(gè)1.4倍的比率基本可以代表了實(shí)際場景(高并發(fā),且客戶端和服務(wù)端不在同一臺機(jī)器上)下它們的單點(diǎn)索引查詢性能差異,而不是之前簡單測試顯示的4倍。
經(jīng)過這樣嚴(yán)格的比較,我終于可以相信PostgreSQL在單點(diǎn)索引查詢上比MongoDB(WiredTiger引擎)快了那么一點(diǎn)點(diǎn)。
結(jié)合前兩次測試結(jié)果,最終的總結(jié)如下
1)加載
? WiredTiger的性能是PG的3倍(注1,注2)
2)插入
?相差不大,WiredTiger小勝(注1,注2)
3)全表掃描(0匹配)
?WiredTiger的性能是PG的4倍
4)單點(diǎn)索引掃描
?PG的性能是WiredTiger的1.4倍(注1)
5)數(shù)據(jù)大小
?PG的數(shù)據(jù)大小是WiredTiger的3倍
注1)以服務(wù)端進(jìn)程CPU消耗作為衡量指標(biāo)的,忽略了MongoDB客戶端的高CPU消耗。
注2)僅僅是單并發(fā)的測試數(shù)據(jù)
這個(gè)結(jié)果雖然和開頭那個(gè)EnterpriseDB的流傳較廣的測試結(jié)果有很大出入,但PG的NoSQL特性在單機(jī)環(huán)境下仍然有巨大的優(yōu)勢(即:NoSQL+SQL+ACID)。
總結(jié)
以上是生活随笔為你收集整理的为什么PostgreSQL比MongoDB还快之完结篇(深挖单点索引查询)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 张萍萍 计科高职13-1 2013030
- 下一篇: 自动上传下载