-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_indexes.py
140 lines (115 loc) · 4.33 KB
/
test_indexes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import psycopg2
from utils.misc import psql_activate_trigram, psql_activate_unaccent, psql_explain_analyse, psql_set_timeout, psql_vacuum_analyse, timed_call
CONNECTION_PARAMS = "dbname=master"
UNACCENT_METHOD = 'unaccent'
TABLE = "model_a"
def create_table(conn):
with conn.cursor() as cur:
cur.execute(f"""
DROP TABLE IF EXISTS {TABLE};
CREATE TABLE IF NOT EXISTS {TABLE} (
id SERIAL PRIMARY KEY,
name TEXT
);
""")
conn.commit()
def create_unaccent_method(conn):
with conn.cursor() as cur:
cur.execute(f"""
REPLACE FUNCTION {UNACCENT_METHOD}(text)
RETURNS text LANGUAGE SQL IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT unaccent('public.unaccent', $1)
$func$
""")
conn.commit()
def create_gin_index(conn):
with conn.cursor() as cur:
cur.execute(f"""
CREATE INDEX {TABLE}_gin ON {TABLE} USING gin(name gin_trgm_ops);
""")
def create_unaccent_gin_index(conn):
with conn.cursor() as cur:
cur.execute(f"""
CREATE INDEX {TABLE}_gin_unaccent ON {TABLE} USING gin({UNACCENT_METHOD}(name) gin_trgm_ops);
""")
def create_index(conn):
with conn.cursor() as cur:
cur.execute(f"""
CREATE INDEX {TABLE}_index ON {TABLE} USING (name);
""")
def create_row(conn, todo):
with conn.cursor() as cur:
cur.execute(f"""
INSERT INTO {TABLE} (name)
SELECT
repeat(md5(s::text), 40)
FROM generate_series(1, {todo}) AS s
""")
conn.commit()
psql_activate_trigram(CONNECTION_PARAMS)
psql_activate_unaccent(CONNECTION_PARAMS)
psql_set_timeout(CONNECTION_PARAMS, 60)
with psycopg2.connect(CONNECTION_PARAMS) as conn:
create_unaccent_method(conn)
timed_call(create_table, conn)
timed_call(create_row, conn, 100_000)
timed_call(psql_vacuum_analyse, CONNECTION_PARAMS, TABLE)
# Odoo SH
"""
CREATE SCHEMA IF NOT EXISTS unaccent_schema;
CREATE EXTENSION IF NOT EXISTS unaccent SCHEMA unaccent_schema;
CREATE OR REPLACE FUNCTION public.o_unaccent(text)
RETURNS text AS
$func$
SELECT unaccent_schema.unaccent('unaccent_schema.unaccent', $1)
$func$ LANGUAGE sql IMMUTABLE;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA unaccent_schema TO public;
GRANT USAGE ON SCHEMA unaccent_schema TO public;
"""
def tests(conn):
with conn.cursor() as cur:
print("Normal ilike:")
query_normal = f"""
SELECT 1 FROM {TABLE} WHERE name ILIKE '%a8a6%'
"""
psql_explain_analyse(cur, query_normal) # warmup
print(psql_explain_analyse(cur, query_normal))
print("\nO_Unaccent ilike (Immutable):")
query_unaccent = f"""
SELECT 1 FROM {TABLE} WHERE o_unaccent(name) ILIKE o_unaccent('%a8a6%')
"""
psql_explain_analyse(cur, query_unaccent) # warmup
print(psql_explain_analyse(cur, query_unaccent))
print("\nUnaccent ilike:")
query_unaccent = f"""
SELECT 1 FROM {TABLE} WHERE public.unaccent(name) ILIKE public.unaccent('%a8a6%')
"""
psql_explain_analyse(cur, query_unaccent) # warmup
print(psql_explain_analyse(cur, query_unaccent))
print("\nUnaccent (odoo) ilike:")
query_unaccent = f"""
SELECT 1 FROM {TABLE} WHERE {UNACCENT_METHOD}(name) ILIKE {UNACCENT_METHOD}('%a8a6%')
"""
psql_explain_analyse(cur, query_unaccent) # warmup
print(psql_explain_analyse(cur, query_unaccent))
print()
print("WITHOUT INDEX")
with psycopg2.connect(CONNECTION_PARAMS) as conn:
tests(conn)
with psycopg2.connect(CONNECTION_PARAMS) as conn:
timed_call(create_gin_index, conn)
timed_call(psql_vacuum_analyse, CONNECTION_PARAMS, TABLE)
print()
print("WITH GIN INDEX")
with psycopg2.connect(CONNECTION_PARAMS) as conn:
tests(conn)
with psycopg2.connect(CONNECTION_PARAMS) as conn:
timed_call(create_unaccent_gin_index, conn)
timed_call(psql_vacuum_analyse, CONNECTION_PARAMS, TABLE)
print()
print("WITH Unaccent GIN INDEX")
with psycopg2.connect(CONNECTION_PARAMS) as conn:
tests(conn)
# COALESCE("ir_translation"."value", "model"."field") ilike '%pattern%'
# ("ir_translation"."value" IS NOT NULL and "ir_translation"."value" ilike '%pattern%') OR ("ir_translation"."value" IS NULL and "model"."field" ilike '%pattern%')