|
| 1 | +""" |
| 2 | +CREATE TABLE location ( |
| 3 | + id SERIAL PRIMARY KEY, |
| 4 | + name VARCHAR NOT NULL, |
| 5 | + parent_path VARCHAR NOT NULL |
| 6 | +); |
| 7 | +
|
| 8 | +INSERT INTO location (name, parent_path) |
| 9 | +SELECT md5(random()::text), |
| 10 | +CASE |
| 11 | + WHEN s = 1 THEN '1/' |
| 12 | + WHEN s < 100 THEN '1/' || (random() * s)::int::text || '/' || s |
| 13 | + ELSE '1/' || (random() * 100)::int::text || '/' || (((random() * s) - 100) + 100)::int::text || '/' || s |
| 14 | +END |
| 15 | +FROM generate_series(1, 100000) AS s; |
| 16 | +
|
| 17 | +CREATE INDEX tgrm_name ON location USING gin(name gin_trgm_ops); |
| 18 | +CREATE INDEX parent_path_index ON location (parent_path); |
| 19 | +
|
| 20 | +""" |
| 21 | + |
| 22 | +# Trigram test |
| 23 | +""" |
| 24 | +-- NOW: |
| 25 | +EXPLAIN ANALYSE SELECT id FROM location |
| 26 | +WHERE name ilike '%ebb0%' OR name ilike '%bcb2%'; |
| 27 | +
|
| 28 | +-- Simpler query plan and sightly better |
| 29 | +EXPLAIN ANALYSE SELECT id FROM location |
| 30 | +WHERE name ILIKE ANY (array['%ebb0%', '%bcb2%']); |
| 31 | +
|
| 32 | +-- NOW: |
| 33 | +EXPLAIN ANALYSE SELECT id FROM location |
| 34 | +WHERE name ilike '%ebb0%' OR name ilike '%bcb2%' OR name ilike '%cb26%' OR name ilike '%aaa2%' OR name ilike '%cccc%'; |
| 35 | +
|
| 36 | +-- Simpler query plan but the cost is sightly higher |
| 37 | +EXPLAIN ANALYSE SELECT id FROM location |
| 38 | +WHERE name ILIKE ANY (array['%ebb0%', '%bcb2%', '%cb26%', '%aaa2%', '%cccc%']); |
| 39 | +
|
| 40 | +-- NOW: |
| 41 | +EXPLAIN ANALYSE SELECT id FROM location |
| 42 | +WHERE name ilike '%ebb0%' OR name ilike '%bcb2%' OR name ilike '%cb26%' OR name ilike '%aaa2%' OR name ilike '%cccc%' |
| 43 | +OR name ilike '%8b1a%' OR name ilike '%214c%' OR name ilike '%851d1b4%' OR name ilike '%1e91a74%' OR name ilike '%e81dbcd%'; |
| 44 | +
|
| 45 | +-- Simpler query plan and sightly better |
| 46 | +EXPLAIN ANALYSE SELECT id FROM location |
| 47 | +WHERE name ILIKE ANY (array['%ebb0%', '%bcb2%', '%cb26%', '%aaa2%', '%cccc%', |
| 48 | +'%8b1a%', '%214c%', '%851d1b4%', '%1e91a74%', '%e81dbcd%']); |
| 49 | +
|
| 50 | +-- NOW: |
| 51 | +EXPLAIN ANALYSE SELECT id FROM location |
| 52 | +WHERE name ilike '%eb%' OR name ilike '%bc%'; |
| 53 | +
|
| 54 | +-- Simpler query plan and sightly better |
| 55 | +EXPLAIN ANALYSE SELECT id FROM location |
| 56 | +WHERE name ILIKE ANY (array['%eb%', '%bc%']); |
| 57 | +""" |
| 58 | + |
| 59 | +# Parent_path test |
| 60 | +""" |
| 61 | +-- NOW: |
| 62 | +EXPLAIN ANALYSE SELECT id FROM location |
| 63 | +WHERE parent_path LIKE '1/93/64/%' OR parent_path LIKE '1/19/%'; |
| 64 | +
|
| 65 | +-- Worst :'( |
| 66 | +EXPLAIN ANALYSE SELECT id FROM location |
| 67 | +WHERE parent_path LIKE ANY (array['1/93/64/%', '1/19/%']); |
| 68 | +
|
| 69 | +
|
| 70 | +-- NOW: |
| 71 | +EXPLAIN ANALYSE SELECT id FROM location |
| 72 | +WHERE parent_path LIKE '1/93/64/%' OR parent_path LIKE '1/19/%' |
| 73 | +OR parent_path LIKE '1/85/96/%' OR parent_path LIKE '1/52/52/%' OR parent_path LIKE '1/5/100/%'; |
| 74 | +
|
| 75 | +-- Worst :'( |
| 76 | +EXPLAIN ANALYSE SELECT id FROM location |
| 77 | +WHERE parent_path LIKE ANY (array['1/93/64/%', '1/19/%', '1/85/96/%', '1/52/52/%', '1/5/100/%']); |
| 78 | +
|
| 79 | +-- Special case, same prefix |
| 80 | +-- NOW: |
| 81 | +EXPLAIN ANALYSE SELECT id FROM location |
| 82 | +WHERE parent_path LIKE '1/93/%' OR parent_path LIKE '1/93/52/%' OR parent_path LIKE '1/93/58/%'; |
| 83 | +
|
| 84 | +-- Worst :'( |
| 85 | +EXPLAIN ANALYSE SELECT id FROM location |
| 86 | +WHERE parent_path LIKE ANY (array['1/93/%', '1/93/52/%', '1/93/58/%']); |
| 87 | +
|
| 88 | +--Simplification |
| 89 | +EXPLAIN ANALYSE SELECT id FROM location |
| 90 | +WHERE parent_path LIKE '1/93/%'; |
| 91 | +
|
| 92 | +""" |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | +"""USELESS SOLUTION |
| 97 | +-- Very slow |
| 98 | +EXPLAIN ANALYSE SELECT id FROM location |
| 99 | +WHERE name ILIKE ANY (values ('%ebb0%'), ('%bcb2%'), ('%cb26%'), ('%aaa2%'), ('%cccc%')); |
| 100 | +""" |
| 101 | + |
0 commit comments