У меня есть 3 таблицы Person, Names и Notes. Каждый человек имеет несколько имен и имеет дополнительные примечания. У меня есть полный текстовый поиск по некоторым столбцам на именах и заметках (см. Ниже), они отлично работают, если слово, которое я ищу, находится в результирующем наборе или находится в db, это для пользовательских функций, php и psql. Проблема теперь в том, что когда слово I search отсутствует в db, запрос получает очень медленное значение в php и пользовательской функции, но все же быстро на psql. На psql оно меньше 1 с, другие - более 10 секунд.Postgresql Медленно на пользовательской функции, php, но быстро, если непосредственно вводить на psql, используя текстовый поиск с индексом gin
Таблицы:
Person | id, birthday
Name | person_id, name, fs_name
Notes | person_id, note, fs_note
Кроме PK и FK индекс, индекс Gin на fs_name и fs_note.
Функция/Query
create or replace function queryNameFunc (TEXT)
returns TABLE(id int, name TEXT) as $$
select id, name
from person_name pnr
inner join person pr on (pnr.person_id=pr.id)
left join personal_notes psr on (psr.person_id = pr.id)
where pr.id in
(select distinct(id)
from person_name pn
inner join person p on (p.id = pn.person_id)
left join personal_notes ps on (ps.person_id = p.id)
where tname @@ to_tsquery($1)
limit 20);
$$ language SQL;
где условие урезана здесь, так, например, если я 'JOHN & Пробок на $ 1, и данные на БД, то результаты быстро, но если «john and james» не находятся в db, то он медленный. Это стало медленнее, поскольку у меня есть записи 1M на человека и 3M + по именам (все фиктивные записи). Любая идея о том, как это исправить? Я попытался перезапустить сервер, перезапустив postgresql.
большой, его рабочий большой вопрос, какая часть ИСПОЛЬЗУЕТ 1 доллар, означает ли это, если у меня есть несколько аргументов, которые я бы сделал, ИСПОЛЬЗУЯ 1, 2, 3? И если у меня есть несколько аргументов, лучше ли это делать на if-else или где условие является частью аргумента? ($ 1 == "tname @@ ..") Большое спасибо – monmonja
Да, ИСПОЛЬЗУЙТЕ $ 1, $ 2, $ 3, как вы используете несколько параметров. ИСПОЛЬЗОВАНИЕ избегает SQLinjection внутри функции, поэтому вам нужно это, когда у вас есть динамические запросы (EXECUTE). –