повысить скорость sqlite, когда данные не хранятся в кэше - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть программное обеспечение, которое работает непрерывно и периодически читает из БД.На какой-то платформе мы наблюдали, что иногда чтения выполнялись очень медленно, и мы выяснили, что это происходит из-за очистки кэша, выполняемого операционной системой.

Я повторил проблему в следующем сценарии:

import subprocess
from subprocess import call
import time
import pandas as pd
import numpy as np
from sqlalchemy.orm import sessionmaker
from sqlalchemy import func, distinct, text
from sqlalchemy.ext.hybrid import hybrid_method
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, create_engine, and_
import os



n_users = 1000
n_days = 60
n_domains = 100
all_users = ['user%d' % i for i in range(n_users)]
all_domains = ['domain%d' % i for i in range(n_domains)]
n_rows = n_users*n_days*n_domains


Base = declarative_base()

#file_path = '/home/local/CORVIL/lpuggini/Desktop/example.db'
file_path = '/data/misc/luca/example.db'
db_path = 'sqlite:///' + file_path


engine = create_engine(db_path)


def get_session():
    Session = sessionmaker(bind=engine)
    session = Session()
    Base.metadata.create_all(engine)
    return session


class DailyUserWebsite(Base):
    __tablename__ = 'daily_user_website'

    id = Column(Integer, primary_key=True)
    user = Column(String(600), index=True)
    domain = Column(String(600))
    time_secs = Column(Integer, index=True)

    def __repr__(self):
        return "DailyUserWebsite(user='%s', domain='%s', time_secs=%d)" % \
            (self.user, self.domain, self.time_secs)


def get_df_daily_data_per_users(users):
    session = get_session()
    query = session.query(DailyUserWebsite).filter(DailyUserWebsite.user.in_(users))
    df = pd.read_sql(query.statement, query.session.bind)
    session.close()
    return df


def create_db():
    if os.path.exists(file_path):
        os.remove(file_path)

    session = get_session()
    batch_size = 10000
    n_iter = int(n_rows / batch_size) + 1
    for i in range(n_iter):
        print 'Building db iteration %d out of %d' % (i, n_iter)
        df = pd.DataFrame()
        df['user'] = np.random.choice(all_users, batch_size)
        df['domain'] = np.random.choice(all_domains, batch_size)
        df['time_secs'] = [x - x%(3600*24) for x in np.random.randint(0, 3600*24*60, batch_size)]
        df.to_sql('daily_user_website', engine, if_exists='append', index=False)


create_db()
for i in range(20):
    users = np.random.choice(all_users, 200)
    t0 = time.time()
    df = get_df_daily_data_per_users(users)
    t1 = time.time()
    print 'it=', i, 'time taken to read %d rows %f ' % (df.shape[0],  t1-t0)
    if i % 5 == 0:
        print 'Clean cache'
        os.system("sync; echo 3 > /proc/sys/vm/drop_caches")

, который генерирует следующие выходные данные:

(samenv) probe686:/data/misc/luca # python db_test.py
it= 0 time taken to read 1089089 rows 8.058407 
Clean cache
it= 1 time taken to read 1099234 rows 104.352085 
it= 2 time taken to read 1087292 rows 8.189860 
it= 3 time taken to read 1077284 rows 8.176948 
it= 4 time taken to read 1057111 rows 7.980002 
it= 5 time taken to read 1075694 rows 8.144479 
Clean cache
it= 6 time taken to read 1117925 rows 106.357740 
it= 7 time taken to read 1124208 rows 8.523779 
it= 8 time taken to read 1083049 rows 8.368766 
it= 9 time taken to read 1112264 rows 9.233548 
it= 10 time taken to read 1098628 rows 8.316519 
Clean cache

Есть ли способ улучшить скорость после кэшированияочистка или смягчение эффекта?

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