У меня есть вариант использования, когда пользователь может вводить текст, и система выполняет поиск соответствующих счетов.Введенный в текст текст может совпадать в нескольких полях как счета-фактуры, так и строк счетов-фактур.
Пользователь имеет доступ только к подмножеству всех счетов-фактур на основе ролей.Но это может быть список из тысяч счетов.
Поиск выполняется прямым поиском в сочетании с подстановочными знаками.(Запросы пишутся на hql)
, показывая результат, мы хотим ограничить его до 50, чтобы не выбирать / обрабатывать тысячи записей в зависимости от того, что пользователь искал.Однако способ присоединения к этому пределу не может быть принудительно введен в действие базой данных.
Раньше у нас было что-то вроде (псевдокод)
select * from tbl_invoice
join tbl_useraccess .... :userid //a few joins happen here to limit to invoices
//where the user has access to
where number like :input
or name like :input
or id in (select id from InvoiceLine where reference like :input)
limit top 50
Это имеет очень плохую производительность, так какпоиск выполняется по каждой строке счета-фактуры, а не только по тем, к которым у вас есть доступ, но всегда дает правильные 50 строк.
Я изменил это на
select * from tbl_invoice invoice
join tbl_useraccess .... :userid
join tbl_invoiceline line on invoice.id = line.invoice_id
where number like :input
or name like :input
or line.reference like :input
limit top 50
ПроизводительностьЭто намного лучше (предыдущий оператор будет просто тайм-аут), но ограничение не работает, потому что может быть несколько строк для одного счета.
Мы могли бы получить все результаты из базы данных, сопоставить их с объектами java и сделать до 50 результатов в Java, но я боюсь, что это может взорвать нашу память, если пользователь получит тысячи миллионов записей,
Итак, в заключение, я ищу лучший способ получить фиксированный список результатов, но также могу искать в связанной 1-n сущности