我通过将100万个条目插入唯一的ID和一些数组类型值的组合来比较Postgres和LMDB。在Postgres中,我使用jsonb来存储数组,并在LMDB中使用它作为属性和多值属性。
我在具有6GB RAM的Debian VM上运行了该测试。
Postgres比LMDB快很多。即使当我通过检查数组中是否存在值来搜索数组类型值时,也是如此。 json列未建立索引,我正在寻找json数组中是否存在值。
基于我已经阅读的内容,他们都使用了B树。
因此,至少在某些情况下,不应该将内存映射的LMDB比Postgres更快。
这是我用来将数据插入Postgres和MDB的脚本。
Postgres:
import psycopg2
import random
import string
import json
import time
connection = psycopg2.connect("dbname='name' user='user' host='localhost' password='test'")
cursor = connection.cursor()
count = 698595
ports = [80, 143, 3389, 22, 21, 8080, 443, 289, 636]
def get_random_ports():
l_ports = list(ports)
num_service = random.randrange(len(ports))
result = []
for i in range(num_port):
l_i = random.randrange(len(l_ports))
result.append(l_ports[l_i])
l_services.pop(l_i)
return result
def get_random_string():
stringLength = random.randrange(5, 15)
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for _ in range(stringLength))
def show_progress(n):
print "|" + ("".join("." for _ in range(n))) + ("".join(" " for _ in range(99 - n))) + "|", "\r" if n < 100 else "\n",
start_time = time.time()
postgres_insert_query = """ INSERT INTO test (port, name) VALUES (%s::jsonb, %s)"""
current_count = 0.0
while current_count < count:
record_to_insert = (
json.dumps({"services": get_random_services()}),
get_random_name()
)
try:
cursor.execute(postgres_insert_query, record_to_insert)
connection.commit()
current_count = current_count + 1
show_progress(int((current_count / count) * 100))
except Exception as err:
print(err)
connection.rollback()
connection.close()
print(str(time.time() - start_time))
MDB:
import uuid
import random
import string
import json
import time
import ldap
from ldap import modlist
connection = ldap.initialize('ldapi:///')
connection.simple_bind_s('cn=admin,dc=local', 'doc')
count = 1
ports = [80, 143, 3389, 22, 21, 8080, 443, 289, 636]
def get_random_ports():
l_ports = list(ports)
num_service = random.randrange(len(ports))
result = []
for i in range(num_port):
l_i = random.randrange(len(l_ports))
result.append(l_ports[l_i])
l_services.pop(l_i)
return result
def get_random_name():
stringLength = random.randrange(5, 15)
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for _ in range(stringLength))
start_time = time.time()
session_id = bytes(str(uuid.uuid4()), 'utf-8')
while count > 0:
try:
name = bytes(get_random_hostname(), 'utf-8')
entry = ldap.modlist.addModlist(
{
"name": name,
"port": get_random_services(),
"objectClass": bytes('tmp', 'utf-8')
}
)
connection.add_s('name=' + name + ",dc=local", entry)
count = count - 1
except Exception as err:
pass
print(str(time.time() - start_time))
分别插入1M个条目后。我尝试了对名称和端口的基本搜索。无需运行多个搜索,因为openldap不会在1秒内返回。如果还需要其他信息。请让我知道。
几年前,我在一个经过适当调优/配置的OpenLDAP实例上进行了测试,该实例具有500万个条目数据库,back-mdb的性能约为61,000次读取/秒。而且肯定有可能获得比这更高的性能,我正在尝试一种特别详尽的方法。
[通常,您似乎已经购买了一个不知道如何正确使用软件的软件,并因此得出了结论。更好的方法是更多地了解您对测试感兴趣的基础软件,以便能够得出准确的结论。