postgresql 为什么postgres比LMDB快?[已关闭]

q8l4jmvw  于 2023-03-01  发布在  PostgreSQL
关注(0)|答案(2)|浏览(207)
    • 已关闭**。此问题为opinion-based。当前不接受答案。
    • 想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。

1年前关闭。
Improve this question
我比较了Postgres和LMDB,在每个文件中插入了100万个条目,每个条目都有唯一的ID和一些数组类型的值,在Postgres中我使用jsonb存储数组,在LMDB中使用属性和多值属性。
我在一个6GB内存的Debian VM上运行了这个测试。
Postgres比LMDB快得多。即使当我通过检查数组中是否存在值来搜索数组类型值时。其中json列没有索引,我正在查找json数组中是否存在值。
根据我所读到的,他们都使用了B树。
所以内存Map的LMDB不应该比Postgres快吗,至少在某些情况下。
下面是我用来将数据插入Postgres和MDB的脚本。
邮政:

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没有返回1s。如果有一些其他信息需要。请让我知道。

hxzsmxv2

hxzsmxv21#

几年前我在一个经过适当调整/配置的OpenLDAP示例上进行了测试,该示例有一个500万条目的数据库,back-mdb的性能大约为61,000次读取/秒。当然,有可能获得比这更高的性能,我尝试了一些特别详尽的东西。
https://mishikal.wordpress.com/2013/05/16/openldap-a-comparison-of-back-mdb-and-back-hdb-performance/

cld4siwp

cld4siwp2#

我知道我在回答一个很老的问题,但我是为将来可能遇到这个问题的人回答的。
因此,问题的根源在于,虽然您可能使用LMDB作为OpenLDAP示例的后备存储,但这并不意味着您获得了与直接使用LMDB相同的性能。OpenLDAP并非设计用于存储任意数据,而是设计用于存储组织目录和身份验证信息。
要进行直接比较,您需要使用类似https://lmdb.readthedocs.io/en/release/的库
此外,您发布的代码不起作用(您正在调用不存在的get_random_services(),但我认为您的意思是调用在您的代码中定义的get_random_ports()),并且不会是评估这两种情况的准确方法,因为您盲目地沉默了可能告诉您超时或连接问题的异常。

相关问题