开发者社区> 问答> 正文

Sqlite3读写速度跟什么有关?

同一个Python脚本,测试读写sqlite3 1000次所用的时间,在四台机器上测试,发现结果差别巨大,搞不清到底跟什么指标有关系。请大神指点。

测试结果如下:

(1)个人工作PC,I5-7400,Win10,Python2。

测试结果如下图所示,总耗时178.8秒。

image.png 2)公司40核服务器,Ubuntu,Python2。

测试结果如下图所示,总耗时3.8秒。image.png )徐州租用32核服务器,Ubuntu,Python2。

测试结果如下图所示,总耗时272.8秒。image.png (4)阿里云1核云主机,Ubuntu,Python2。

测试结果如下图所示,总耗时9.6秒。image.png image.png


# coding: utf-8
# speed_test.py

import zlib
import pickle
import time
import sqlite3
from datetime import datetime
            
            
def sqlite_test():
    """测试sqlite读写速度
    """
    # 待写入数据html
    with open('page.html') as f:
        html = f.read()
    print 'Original data size = {}'.format(len(html))    

    # 连接sqlite数据库,创建表
    start_time = time.time()
    conn = sqlite3.connect('test.db', timeout=10000, isolation_level=None, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
    conn.text_factory = lambda x: unicode(x, 'utf-8', 'replace') 
    sql = """
    CREATE TABLE IF NOT EXISTS cache (
        key TEXT NOT NULL PRIMARY KEY UNIQUE,
        value BLOB,
        updated timestamp DEFAULT (datetime('now', 'localtime'))
    );
    """
    conn.execute(sql)
    conn.execute("CREATE INDEX IF NOT EXISTS keys ON cache (key);")
    print 'Time used to create sqlite database: {} seconds.'.format(round(time.time() - start_time, 2))
    
    # 读写1000次测试
    test_times = 1000
    all_times_used = []
    start_time = time.time()
    for i in range(test_times):
        # 写入数据
        updated = datetime.now()
        key = 'cache-{}'.format(i)
        # 写数据
        conn.execute("INSERT OR REPLACE INTO cache (key, value, updated) VALUES(?, ?, ?);", (
            key, html, updated)
        ) 
        # 读取数据
        row = conn.execute("SELECT value, updated FROM cache WHERE key=?;", (key,)).fetchone()
        i += 1
        if i % 100 == 0:
            # 每100次,输出一次用时
            times_used = round(time.time() - start_time, 2)
            all_times_used.append(times_used)
            print '[{}] {}'.format(times_used, i)
            start_time = time.time()
    print 'Total used {} seconds, avg time used for per write-read op: {} seconds.'.format(sum(all_times_used), round(sum(all_times_used)/float(test_times), 4))


if __name__ == '__main__':
    sqlite_test()

展开
收起
因为相信,所以看见。 2020-05-24 22:06:05 585 0
1 条回答
写回答
取消 提交回答
  • 和线程无关,sqlite是单线程写操作。

    关闭wal模式,默认是开。打开只是加一个类似log的缓存,定时入库。

    关闭自动提交,默认是开。建议代码操作使用批量增删改,而不是一句一句执行。

    字段尽可能的不使用TEXT。

    机械磁盘瓶颈2G,SSD瓶颈12G。亲测过。

    2021-02-07 14:18:27
    赞同 展开评论 打赏
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
微信SQLite数据库损坏恢复实践 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载