В настоящее время у меня есть следующее:
User (id, fname, lname, deleted_at, guest)
Я могу запросить список пользователей по их инициалам fname
следующим образом:
User Load (9.6ms) SELECT "users".* FROM "users" WHERE (users.deleted_at IS NULL) AND (lower(left(fname, 1)) = 's') ORDER BY fname ASC LIMIT 25 OFFSET 0
Это быстро благодаря следующему индексу:
CREATE INDEX users_multi_idx
ON users (lower(left(fname, 1)), fname)
WHERE deleted_at IS NULL;
Что я хочу сделать сейчас, так это иметь возможность запрашивать всех пользователей, которые не начинаются с буквы A-Z. Я заставил это работать так:
SELECT "users".* FROM "users" WHERE (users.deleted_at IS NULL) AND (lower(left(fname, 1)) ~ E'^[^a-zA-Z].*') ORDER BY fname ASC LIMIT 25 OFFSET 0
Но проблема в том, что этот запрос очень медленный и, похоже, не использует индекс для ускорения первого запроса. Любые предложения о том, как я могу элегантно ускорить второй запрос (не az)?
Я использую Postgres 9.1 с рельсами 3.2.
Спасибо
EXPLAIN ANALYZE
обоих запросов в explain.depesz.com и связали их здесь ( вы должны делать это для всех вопросов о производительности), хотя в этом случае достаточно ясно, что 1-й использует индекс, который не может использовать 2-й. - person Craig Ringer   schedule 16.10.2012