Тест на использование PG в качестве key-value storage для записей фиксированного размера. Замерялась bulk вставка и выбрка записей. Результаты примерно такие:
На oracle 10g цифры на порядок другие.
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# картинка с результатами http://i.imgur.com/gjDOQcX.png | |
NUM_OF_VALUES = 100000 | |
VALUES_PER_COMMIT = 500 | |
import time | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import psycopg2 as pg | |
c = pg.connect("dbname='user' user='user' host='127.0.0.1'") | |
cur = c.cursor() | |
def mkPair((i,v)): | |
return cur.mogrify("(%s, %s)", (i, pg.Binary(v))) | |
def insert(data): | |
cur.execute('insert into xxx (key, value) values %s' % ','.join(map(mkPair, data))) | |
c.commit() | |
def insertMany(n, valSize): | |
pairs = [] | |
for i in range(n): | |
pairs.append((i, 'x' * valSize)) #os.urandom(VALUE_SIZE))) | |
if i % VALUES_PER_COMMIT == 0: | |
insert(pairs) | |
pairs = [] | |
if len(pairs) > 0: | |
insert(pairs) | |
insert_time = [] | |
select_time = [] | |
val_sizes = [128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768] | |
for val_size in val_sizes: | |
cur.execute('drop table if exists xxx') | |
cur.execute('create table xxx (key int primary key, value bytea not null)') | |
c.commit() | |
start = time.time() | |
insertMany(NUM_OF_VALUES, val_size) | |
end = time.time() | |
insert_time.append(end - start) | |
start = time.time() | |
cur.execute('select * from xxx') | |
count = 0 | |
for record in cur: | |
count += 1 | |
end = time.time() | |
select_time.append(end - start) | |
c.close() | |
fig = plt.figure() | |
ax = fig.add_subplot(111) | |
n = np.arange(len(val_sizes)) | |
w = 0.35 | |
ins = ax.bar(n, insert_time, w, color='green', alpha=0.6) | |
sel = ax.bar(n+w, select_time, w, color='blue', alpha=0.6) | |
ax.set_title(u'Вставка и выборка 100k записей') | |
ax.set_ylim(0, max(insert_time)*1.1) | |
ax.set_ylabel(u'Время выполнения запроса, секунды') | |
ax.set_xlabel(u'Размер записей, байты') | |
ax.set_xticks(n+w) | |
ax.set_xticklabels(val_sizes) | |
ax.legend((ins[0],sel[0]), ('Insert', 'Select'), loc=2) | |
def autolabel(rects): | |
d = max(insert_time)*0.02 | |
for r in rects: | |
h = r.get_height() | |
ax.text(r.get_x()+r.get_width()/2., h+d, '%.2f'%h, ha='center', va='bottom') | |
autolabel(ins) | |
autolabel(sel) | |
plt.show() |