Тест на использование 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() |