Вы все еще можете выжать немного.
Во-первых, я бы вообще советовал использовать тип данных text
вместо varchar
.Так что text_pattern_ops
вместо varchar_pattern_ops
.Однако это не повлияет на производительность.
Далее, поскольку ваш столбец содержит до 100 символов, но вы используете только первые n (20?) Символов, индекс будет намного меньше с lower(left(a, 20)
вместо lower(a)
, как я уже предлагал в своем ответе на ваш вопрос к приквелу .
Сам поиск по индексу выполняет то же самое, но сервер должен посетить еще много страниц на диске илив оперативной памятиМеньше строк будет помещаться в ОЗУ или на страницу диска, поэтому для каждого поиска нужно посещать больше страниц.Кроме того, страницы будут выпадать из вашего кэша раньше и т. Д. Это особенно важно для больших таблиц, подобных вашей.Ограничьте диапазон букв, которые можно искать, до необходимого минимума.Это дает вам что-то вроде:
CREATE INDEX t_a_lower_left_idx ON t (lower(left(a, 20)) text_pattern_ops);
Кроме того, вы можете использовать специальные операторы ~>=~
и ~<~
в своем запросе, как я продемонстрировал в ответе , с которым я связан :
SELECT * FROM tbl WHERE lower(a) ~>=~ 'abcde' AND lower(a) ~<~ ('abcdf')
Обратите внимание на 'f' вместо 'e' во втором выражении.Вопрос в том, как получить «следующий» символ в соответствии с локалью «C»?
SELECT chr(ascii('é')+1));
Итак, вы можете:
SELECT * FROM tbl WHERE lower(a) ~>=~ 'abcde'
AND lower(a) ~<~ ('abcd' || chr(ascii('e')+1))
Я выполнил тест с использованием таблицы в натуральном выражении.полмиллиона строк.Поисковый термин, дающий 650 строк, занял 4 мс с первым запросом и 3 мс со вторым.Это очень во многом зависит от того, сколько строк найдено.Для поискового термина, дающего только 1 строку, здесь требуется 0,044 мс.
Поэтому ограничьте минимальную длину поискового термина, чтобы запретить бесполезные запросы, которые в любом случае приводили бы к слишком большому количеству строк.Как минимум 3 или 4 символа.
Далее вы можете кластер свою таблицу следующим образом:
CLUSTER tbl USING t_a_lower_left_idx
После этого мой тестовый сценарий занял 2,5 мс вместо3 мс.
Конечно, применяются все базовые рекомендации по оптимизации производительности .
Если приведенного выше недостаточно, вы можете захотетьподумать о создании табличного пространства на виртуальном диске или в разделе tmpfs (Linux) и создать там индексы или даже поместить всю таблицу целиком.Я уверен, что вы знаете о последствиях для безопасности изменчивой среды для базы данных.Делайте это только в том случае, если вы можете позволить себе потерять все свои данные.
CREATE INDEX t_a_lower_left_idx ON t (lower(left(a, 20)) text_pattern_ops)
TABLESPACE indexspace;
Если ваша база данных настроена правильно, и на вашем компьютере достаточно оперативной памяти, и таблица интенсивно читается, стандартные алгоритмы кэширования могут обеспечить большую часть прироста производительности автоматически, и вы не получите много сэто.