ec2-ubuntu-sqlite3
Сценарий Python записывает тиковые данные в базу данных sqlite3. Для этого я обращаюсь к базе данных, используя следующее:
conn = sqlite3.connect('tick.db', detect_types=sqlite3.PARSE_DECLTYPES, timeout=20,isolation_level=None)
c = conn.cursor()
c.execute('PRAGMA journal_mode=wal')
Одновременно (это отдельный скрипт запускается каждую минуту), я читаю (только) базу данных, используя pandas
.
conn_tick = sqlite3.connect('tick.db', detect_types=sqlite3.PARSE_DECLTYPES, timeout=20,
isolation_level=None)
select_statement = 'select timestamp,close from %sfut where "timestamp" > "%s"' % (bnf, lasttimestamp)
tdf = pd.read_sql(select_statement, conn_tick)
conn_tick.close()
Когда я пытаюсь понять, сколько времени занимает вторая команда, она обычно находится в диапазоне 10-12 секунд, количество строк: 297. Однако, когда количество строк большескажем 1000+. Время увеличивается до 90 секунд.
Я полагаю, это может быть связано с процессом записи, блокирующим базу данных?
Должен ли я изучать postgres или? Является ли что-то в моем коде проблемой, которую я не могу понять?
TIA
---- Редактировать 2 -----
Код записи:
inst_token_list = [260105, 256265, 259, 13177346, 13176834, 486915]
def tick_entry(inst,timestamp,ltp):
if inst == 260105:
c.execute('INSERT INTO bnftick (timestamp, close) VALUES (?,?)',
(timestamp,ltp))
elif inst == 259:
c.execute('INSERT INTO usdinrtick (timestamp, close) VALUES (?,?)',
(timestamp, ltp))
conn.commit()
def tick_entry1(inst,timestamp,ltp, bid, ask):
if inst == 13177346:
c.execute('INSERT INTO niftyfut (timestamp, close, bid, ask) VALUES (?,?,?,?)',
(timestamp, ltp, bid, ask))
elif inst == 13176834:
c.execute('INSERT INTO bnffut (timestamp, close, bid, ask) VALUES (?,?,?,?)',
(timestamp, ltp, bid, ask))
conn.commit()
def on_ticks(ws, ticks):
global c, conn
for t in ticks:
if t['instrument_token'] == 260105:
timestamp = t['timestamp']
ltp = t['last_price']
inst = t['instrument_token']
try:
tick_entry(inst,timestamp,ltp)
except:
# print('problem with db')
pass
elif t['instrument_token'] == 13177346:
timestamp = t['timestamp']
ltp = t['last_price']
inst = t['instrument_token']
bid = t['depth']['buy'][0]['price']
ask = t['depth']['sell'][0]['price']
# print(t, bid, ask)
try:
tick_entry1(inst,timestamp,ltp,bid,ask)
except:
print('Problem with new')
pass
elif t['instrument_token'] == 13176834:
timestamp = t['timestamp']
ltp = t['last_price']
inst = t['instrument_token']
bid = t['depth']['buy'][0]['price']
ask = t['depth']['sell'][0]['price']
# print(t['instrument_token'], bid, ask)
try:
tick_entry1(inst,timestamp,ltp,bid,ask)
except:
print('Problem with new 1')
pass
def on_connect(ws, response):
ws.subscribe(inst_token_list)
ws.set_mode(ws.MODE_FULL, inst_token_list)
# Assign the callbacks.
kws.on_ticks = on_ticks
kws.on_connect = on_connect
# kws.on_close = on_close
# Infinite loop on the main thread. Nothing after this will run.
# You have to use the pre-defined callbacks to manage subscriptions.
kws.connect()
----- Редактировать ----
Как отметил @ipaleka:
С другой стороны, производительность чтения ухудшается по мере того, как WALразмер файла увеличивается, поскольку каждый читатель должен проверять содержимое файла WAL, а время, необходимое для проверки файла WAL, пропорционально размеру файла WAL. Wal-index помогает быстрее находить содержимое в файле WAL, но производительность все равно падает с увеличением размера файла WAL. Следовательно, для поддержания хорошей производительности чтения важно уменьшить размер файла WAL, регулярно проверяя контрольные точки.
Если кто-нибудь сейчас сможет пролить свет на то, насколько этот эффект, скажем, на 10 Мб будетбудьте великолепны.
Теперь посмотрите, как устанавливать контрольные точки.