Last active
November 19, 2020 00:37
-
-
Save agrif/7a55045d0a1b23314b1a0ab9ebe3377b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import sqlite3 | |
import timeit | |
import numpy | |
import tempfile | |
import os.path | |
A_VALUES = ['foo', 'bar', 'baz'] | |
B_VALUES = ['magrat', 'nanny', 'granny'] | |
def make_db(path, make_index, rows=100000): | |
conn = sqlite3.connect(path) | |
conn.execute('''CREATE TABLE files (date integer, a text, b text)''') | |
if make_index: | |
conn.execute('''CREATE INDEX idx_date ON files (date DESC)''') | |
conn.execute('''CREATE INDEX idx_a ON files (a)''') | |
dates = list(range(rows)) | |
random.shuffle(dates) | |
for date in dates: | |
a = random.choice(A_VALUES) | |
b = random.choice(B_VALUES) | |
conn.execute('''INSERT INTO files VALUES (?, ?, ?)''', (date, a, b)) | |
conn.commit() | |
conn.close() | |
def explain(conn, stmt): | |
c = sqlite3.connect(conn) | |
for row in c.execute('EXPLAIN QUERY PLAN ' + stmt): | |
print('\t', row) | |
c.close() | |
def test_once(conn, stmt, repeat=10, number=10): | |
m = numpy.array(timeit.repeat('c = sqlite3.connect(conn); c.execute(stmt); c.close()', | |
globals=dict( | |
conn=conn, stmt=stmt, sqlite3=sqlite3), | |
repeat=repeat, number=number)) | |
m /= number | |
return (numpy.mean(m), numpy.std(m) / numpy.sqrt(len(m))) | |
def test(conn_n, conn_i, stmt, **kwargs): | |
print(stmt) | |
print('\twithout index: {} +/- {}'.format( | |
*test_once(conn_n, stmt, **kwargs))) | |
explain(conn_n, stmt) | |
print('\twith index : {} +/- {}'.format( | |
*test_once(conn_i, stmt, **kwargs))) | |
explain(conn_i, stmt) | |
print() | |
def main(): | |
with tempfile.TemporaryDirectory(prefix='sqlite-speed-test') as d: | |
conn_n = os.path.join(d, 'n.db') | |
make_db(conn_n, False) | |
conn_i = os.path.join(d, 'i.db') | |
make_db(conn_i, True) | |
test(conn_n, conn_i, '''SELECT * FROM files ORDER BY date DESC LIMIT 10''') | |
test(conn_n, conn_i, '''SELECT * FROM files WHERE date >= 99000 ORDER BY date DESC LIMIT 10''') | |
test(conn_n, conn_i, '''SELECT * FROM files WHERE a = 'foo' ORDER BY date DESC LIMIT 10''') | |
test(conn_n, conn_i, '''SELECT * FROM files WHERE date >= 99000 AND a = 'foo' ORDER BY date DESC LIMIT 10''') | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The DBs I used were created using the following (adding/removing a date index as needed):