Как сделать базу данных sqlite3 «только для чтения», в которую выполняется запись? - PullRequest
0 голосов
/ 30 октября 2019
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 Мб будетбудьте великолепны.

Теперь посмотрите, как устанавливать контрольные точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...