根据PostgreSQL的手册,PostgreSQL中hash索引有很大的缺陷,不推荐使用。
http://58.58.27.50:8079/doc/html/9.3.1_zh/indexes-types.html
-----------------------------------------------------------------------------
Hash 索引操作目前没有记录 WAL 日志,因此如果数据库崩溃有未写入的改变, 我们可能需要用REINDEX重建 Hash 索引。另外, 对hash索引的改变在初始的基础备份后不是基于流复制或者基于文件复制的, 所以对于随后使用它们的查询会给出错误的回复。因为这些原因, 我们并不鼓励使用 Hash 索引。
-----------------------------------------------------------------------------
并且hash索引只支持"等于"查询,而PostgreSQL中作为默认索引类型的btree能支持包括“等于”在内的各种比较操作,功能上覆盖了hash索引。因此,在PostgreSQL中,对常规数据类型,btree索引是不二之选。(相比Oracle中有过于丰富的索引类型可选择,在PostgreSQL中建索引是不是更轻松一点?)
那么,既然不推荐使用hash索引,PostgreSQL为什么还要实现hash索引呢?
PostgreSQL的hash索引使用的线性hash算法,可以动态扩展桶数,理论上的查询复杂度接近O(1),这是btree无法比拟的。下面做个实测,也证明了在大数量的情况下,hash索引的性能确实明显优于btree。所以在某些极少的特殊场景下,hash索引也还是可以考虑的。
宿主机
OS:Win7 64bit
CPU:AMD Athlon II X4 640 3.0G
内存:6G
硬盘:Apacer A S510S 128G SATA
虚拟机
OS:CentOS 6.5
CPU:x4核
MEM:2G
PostgreSQL:9.3( shared_buffers=128M )
分别建2个测试数据库db1和db2。db1是原始的pgbench测试数据库,即btree索引。db2则通过下面的方法修改为hash索引。
sclae=1时,无太大差异
数据略
sclae=10时,大概快了20%
sclae=100时,大概快了1倍
2种索引的大小差不多
http://58.58.27.50:8079/doc/html/9.3.1_zh/indexes-types.html
-----------------------------------------------------------------------------
Hash 索引操作目前没有记录 WAL 日志,因此如果数据库崩溃有未写入的改变, 我们可能需要用REINDEX重建 Hash 索引。另外, 对hash索引的改变在初始的基础备份后不是基于流复制或者基于文件复制的, 所以对于随后使用它们的查询会给出错误的回复。因为这些原因, 我们并不鼓励使用 Hash 索引。
-----------------------------------------------------------------------------
并且hash索引只支持"等于"查询,而PostgreSQL中作为默认索引类型的btree能支持包括“等于”在内的各种比较操作,功能上覆盖了hash索引。因此,在PostgreSQL中,对常规数据类型,btree索引是不二之选。(相比Oracle中有过于丰富的索引类型可选择,在PostgreSQL中建索引是不是更轻松一点?)
那么,既然不推荐使用hash索引,PostgreSQL为什么还要实现hash索引呢?
PostgreSQL的hash索引使用的线性hash算法,可以动态扩展桶数,理论上的查询复杂度接近O(1),这是btree无法比拟的。下面做个实测,也证明了在大数量的情况下,hash索引的性能确实明显优于btree。所以在某些极少的特殊场景下,hash索引也还是可以考虑的。
环境
测试环境在Linux虚拟机上宿主机
OS:Win7 64bit
CPU:AMD Athlon II X4 640 3.0G
内存:6G
硬盘:Apacer A S510S 128G SATA
虚拟机
OS:CentOS 6.5
CPU:x4核
MEM:2G
PostgreSQL:9.3( shared_buffers=128M )
测试方法
使用pgbench的TCP-B和Select Only测试对比性能。分别建2个测试数据库db1和db2。db1是原始的pgbench测试数据库,即btree索引。db2则通过下面的方法修改为hash索引。
- [chenhj@hanode1 ~]$ psql db2
- psql (9.3.4)
- Type "help" for help.
-
- db2=# alter table pgbench_accounts DROP CONSTRAINT pgbench_accounts_pkey;
- ALTER TABLE
- db2=# \d pgbench_accounts
- Table "public.pgbench_accounts"
- Column | Type | Modifiers
- ----------+---------------+-----------
- aid | integer | not null
- bid | integer |
- abalance | integer |
- filler | character(84) |
-
- db2=# create index on pgbench_accounts using hash(aid);
- CREATE INDEX
测试结果
sclae=1时,差异不大;sclae=100时,hash几乎是btree的两倍性能。可见数据量越大,hash的性能优势越明显。sclae=1时,无太大差异
数据略
sclae=10时,大概快了20%
点击(此处)折叠或打开
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 db1
- transaction type: TPC-B (sort of)
- scaling factor: 10
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 641
- tps = 213.418248 (including connections establishing)
- tps = 213.716676 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 db2
- transaction type: TPC-B (sort of)
- scaling factor: 10
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 653
- tps = 217.440022 (including connections establishing)
- tps = 217.770471 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 db1
- transaction type: TPC-B (sort of)
- scaling factor: 10
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 2064
- tps = 683.721499 (including connections establishing)
- tps = 701.078622 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 db2
- transaction type: TPC-B (sort of)
- scaling factor: 10
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 3278
- tps = 1085.589348 (including connections establishing)
- tps = 1110.521633 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db1
- transaction type: SELECT only
- scaling factor: 10
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 4922
- tps = 1640.242391 (including connections establishing)
- tps = 1642.450916 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db2
- transaction type: SELECT only
- scaling factor: 10
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 4771
- tps = 1590.028578 (including connections establishing)
- tps = 1592.541658 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 -S db1
- transaction type: SELECT only
- scaling factor: 10
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 32188
- tps = 10724.978992 (including connections establishing)
- tps = 10969.036021 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 -S db2
- transaction type: SELECT only
- scaling factor: 10
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 33367
- tps = 11092.571963 (including connections establishing)
- tps = 11339.707975 (excluding connections establishing)
sclae=100时,大概快了1倍
点击(此处)折叠或打开
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db1
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 1324
- tps = 441.307443 (including connections establishing)
- tps = 442.905056 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db2
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 3226
- tps = 1075.038414 (including connections establishing)
- tps = 1076.599774 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 db1
- transaction type: TPC-B (sort of)
- scaling factor: 100
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 2194
- tps = 725.580208 (including connections establishing)
- tps = 741.318899 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 db2
- transaction type: TPC-B (sort of)
- scaling factor: 100
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 3174
- tps = 1049.927110 (including connections establishing)
- tps = 1073.139131 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db1
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 1385
- tps = 461.481151 (including connections establishing)
- tps = 462.109984 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 1 -T 3 -S db2
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 1
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 3527
- tps = 1175.124543 (including connections establishing)
- tps = 1177.144768 (excluding connections establishing)
-
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 -S db1
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 6313
- tps = 2092.075168 (including connections establishing)
- tps = 2137.468368 (excluding connections establishing)
- [chenhj@hanode1 ~]$ pgbench -n -l -c 16 -T 3 -S db2
- transaction type: SELECT only
- scaling factor: 100
- query mode: simple
- number of clients: 16
- number of threads: 1
- duration: 3 s
- number of transactions actually processed: 14414
- tps = 4775.127727 (including connections establishing)
- tps = 4886.910106 (excluding connections establishing)
2种索引的大小差不多
- db1=# select pg_table_size('pgbench_accounts_pkey'::regclass);
- pg_table_size
- ---------------
- 224641024
- (1 row)
-
- db2=# select pg_table_size('pgbench_accounts_aid_idx'::regclass);
- pg_table_size
- ---------------
- 268451840
- (1 row)