SQLRU.net
Разработка приложений баз данных

Начало » Использование СУБД » Firebird, HQbird, InterBase » Ненужные сканы записей при rows
Ненужные сканы записей при rows [сообщение #5911] Fri, 21 February 2025 12:49 Переход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Добрый день,

Имеем такой запрос:

select
  b.id, b.fdate,
  c.code, c.name
from ta_bundle b
left join ta_entity c on (c.id = b.entity_id)
rows 1000 to 1010

План выполнения:

Select Expression
    -> First N Records
        -> Skip N Records
            -> Nested Loop Join (outer)
                -> Table "TA_BUNDLE" as "B" Full Scan
                -> Filter
                    -> Table "TA_ENTITY" as "C" Access By ID
                        -> Bitmap
                            -> Index "PK_TA_ENTITY" Unique Scan

Сканы записей из таблиц:

TA_BUNDLE - 1010
TA_ENTITY - 1010

Хочется чтобы при больших таблицах и скипов движок читал только нужные 10 записей из TA_ENTITY, а не все 1010.


Через lateral то же самое получается:

select
  b.id, b.fdate,
  c.code, c.name
from ta_bundle b
left join lateral (
  select c.code, c.name
  from ta_entity c
  where c.id = b.entity_id) c on true
rows 1000 to 1010

Работает хорошо только когда подзапрос:

select
  b.id, b.fdate,
  -- ? c.code
  (select c.name from ta_entity c where c.id = b.entity_id)
from ta_bundle b
rows 1000 to 1010

Но так больше одного поля не вытянуть из другой таблицы.
Можно как-то по другому сформировать запрос чтобы движок оптимально сканировал записи?
Тестирую с FB 5.0.1
Re: Ненужные сканы записей при rows [сообщение #5912 является ответом на сообщение #5911] Fri, 21 February 2025 14:27 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Хм.. вот так читает оптимально:

with b as (
  select
    b.id, b.fdate, b.entity_id
  from ta_bundle b
  rows 1000 to 1010
  )
select
  b.id, b.fdate,
  c.code, c.name
from b
left join ta_entity c on (c.id = b.entity_id)
Если по другому никак, то получается генерировать такие монструозные запросы Wink
Re: Ненужные сканы записей при rows [сообщение #5913 является ответом на сообщение #5912] Fri, 21 February 2025 14:38 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 432
Зарегистрирован: August 2022
Senior Member
Чисто из любопытства: ты в курсе, что ROWS без ORDER BY - пустая трата времени?..

Нет способа определить какая запись будет 1000-й, не прочитав предыдущие 999.

Поэтому пагинацию надо делать на клиенте.

[Обновления: Fri, 21 February 2025 14:39]

Известить модератора

Re: Ненужные сканы записей при rows [сообщение #5914 является ответом на сообщение #5913] Fri, 21 February 2025 14:52 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Цитата:
ROWS без ORDER BY - пустая трата времени
есть и order by, конечно, пример урезанный, для понимания сути.

Цитата:
Нет способа определить какая запись будет 1000-й, не прочитав предыдущие 999
Естественно, но достаточно читать записи из ta_bundle, без 1000 чтений из ta_entity.
Важно получать нужный срез из главной таблицы, а потом обогащать датасет дополнительной инфы.

Цитата:
Поэтому пагинацию надо делать на клиенте
Когда миллион записей, не целесообразно делать на клиенте.
Re: Ненужные сканы записей при rows [сообщение #5916 является ответом на сообщение #5914] Sat, 22 February 2025 00:59 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 432
Зарегистрирован: August 2022
Senior Member
Оптимизатор не в курсе, что у тебя связь таблиц 1:1. 1000-я запись результата может быть как первой из ta_bundle, так и миллионной.
Re: Ненужные сканы записей при rows [сообщение #5922 является ответом на сообщение #5916] Mon, 24 February 2025 12:49 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Связь не 1:1. В bundle документы, которые создают субьекты, entity.

Раз Firebird выдает план чтения из ta_entitу как unique scan:

    -> Filter
        -> Table "TA_ENTITY" as "C" Access By ID
            -> Bitmap
                -> Index "PK_TA_ENTITY" Unique Scan

То думаю Firebird знает что максимально можно вытащить одну запись из ta_entitу.
Так как у нас left join c максимум одна запись то это никак не влияет на rows, и соответственно нету смысла дергать эту таблицу при считывания первых 1000 записей из ta_bundle.
Re: Ненужные сканы записей при rows [сообщение #5928 является ответом на сообщение #5922] Mon, 24 February 2025 15:42 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 432
Зарегистрирован: August 2022
Senior Member
marcodor писал(а) Mon, 24 February 2025 10:49
думаю Firebird знает что максимально можно вытащить одну запись из ta_entitу.
А ещё Firebird знает, что минимально это ноль записей. А сколько реально записей результата в первой тысяче - не знает.

Сам попробуй решить эту задачку собственным натуральным интеллектом: тысячная запись из ta_entity это первая, 500-я или тысячная запись результата? Сколько ещё записей надо пропускать после неё?
Re: Ненужные сканы записей при rows [сообщение #5930 является ответом на сообщение #5928] Mon, 24 February 2025 18:09 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
SD, еще раз, у нас выборка из ta_bundle, там ограничение по rows, и там важно сколько записей пропустить, и какие дальше выдавать клиенту.

Дальше для каждой записи из ta_bundle которое попали в rows мы делаем left join ta_entity и берем имя компании, то есть она никак не влияет на общее количество выданных записей и очередность. Или c left join ta_entity, или без, те же записи будут из ta_bundle.

Так вот, почему Firebird читает и для пропущенных записей (первая тысяча) из дополнительной таблицы ta_entity, непонятно, ведь она никак не влияет на rows.
Re: Ненужные сканы записей при rows [сообщение #5932 является ответом на сообщение #5930] Tue, 25 February 2025 09:28 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время в онлайне  sim_84
Сообщений: 341
Зарегистрирован: June 2022
Senior Member
В целом твои рассуждения верны, но в настоящее время оптимизатор Firebird никак не использует факт о наличии ограничений и потому first/skip, rows, fetch/offset работают по общим для всех случаев правилам.

Вот когда он будет уметь использовать ограничения целостности для трансформации запросов в другой вид, то возможно внутри будет выполняться что-то вроде твоего запроса с with.

И это поможет не только c rows, но и например  в таких случаях

create view v as
select
  b.id, b.fdate,
  c.code, c.name
from ta_bundle b
left join ta_entity c on c.id = b.entity_id;

select count(*) from v;
в последнем случае вообще можно удалить left join ибо не не влияет на результат.

Re: Ненужные сканы записей при rows [сообщение #5933 является ответом на сообщение #5932] Tue, 25 February 2025 09:56 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Сложно ли такое реализовывать? Я готов немного спонсировать.
Или забить на все и переделывать все запросы с CTE.
Сейчас практически все проекты на вебе и много пагинаций.
Когда левая часть тяжёлая то это существенно влияет на производительность.
Интересно как Postgres обрабатывает такие случаи.. проверю на выходные.
Re: Ненужные сканы записей при rows [сообщение #5934 является ответом на сообщение #5933] Tue, 25 February 2025 10:22 Переход к предыдущему сообщениюПереход к следующему сообщению
pastor в настоящее время не в онлайне  pastor
Сообщений: 95
Зарегистрирован: June 2022
Географическое положение: Калуга
Member
marcodor писал(а) Tue, 25 February 2025 09:56
Сложно ли такое реализовывать? Я готов немного спонсировать.
Или забить на все и переделывать все запросы с CTE.
Сейчас практически все проекты на вебе и много пагинаций.
Когда левая часть тяжёлая то это существенно влияет на производительность.
Интересно как Postgres обрабатывает такие случаи.. проверю на выходные.
в общем виде задача решения не имеет. точнее имеет только для однопользовательского блокировочника.

самое простое - переделать на ХП с указанием точки старта
там все знаете в вашей предметной области для каждой конкретной таблицы - фильтры, сортировки, критичнось к вставкам изменениям и пр.
можно через временные таблицы, можно через сессионные
Re: Ненужные сканы записей при rows [сообщение #5935 является ответом на сообщение #5934] Tue, 25 February 2025 13:59 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время в онлайне  sim_84
Сообщений: 341
Зарегистрирован: June 2022
Senior Member
> в общем виде задача решения не имеет

Имеет. Я же уже сказал, что одним из видов оптимизации является Query Transformation, который сам может преобразовать запрос в эквивалентную форму.

Про версионники vs блокировочники бред. Автор спрашивал про сам SQL. Как обеспечивается согласованность между двумя переходами на страницу к теме не относится. Оно нормально не будет работать ни в блокировочнике, ни в версионнике.
Re: Ненужные сканы записей при rows [сообщение #5936 является ответом на сообщение #5935] Tue, 25 February 2025 17:58 Переход к предыдущему сообщениюПереход к следующему сообщению
basid в настоящее время не в онлайне  basid
Сообщений: 174
Зарегистрирован: June 2022
Географическое положение: Asia/Irkutsk
Senior Member
sim_84 писал(а) Tue, 25 February 2025 18:59
Как обеспечивается согласованность между двумя переходами на страницу к теме не относится. Оно нормально не будет работать ни в блокировочнике, ни в версионнике.
... и мы опять плавно переходим к тому, что постраничную выдачу может делать клиент.
Получив от сервера весь набор данных и разбивая его на куски нужного размера любых подходящим способом.
Re: Ненужные сканы записей при rows [сообщение #5937 является ответом на сообщение #5936] Wed, 26 February 2025 07:58 Переход к предыдущему сообщениюПереход к следующему сообщению
pastor в настоящее время не в онлайне  pastor
Сообщений: 95
Зарегистрирован: June 2022
Географическое положение: Калуга
Member
basid писал(а) Tue, 25 February 2025 17:58
sim_84 писал(а) Tue, 25 February 2025 18:59
Как обеспечивается согласованность между двумя переходами на страницу к теме не относится. Оно нормально не будет работать ни в блокировочнике, ни в версионнике.
... и мы опять плавно переходим к тому, что постраничную выдачу может делать клиент.
Получив от сервера весь набор данных и разбивая его на куски нужного размера любых подходящим способом.
или сервер Smile
при введении в оборот сущности сессия
Re: Ненужные сканы записей при rows [сообщение #5938 является ответом на сообщение #5936] Wed, 26 February 2025 09:23 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время в онлайне  sim_84
Сообщений: 341
Зарегистрирован: June 2022
Senior Member
basid писал(а) Tue, 25 February 2025 17:58
sim_84 писал(а) Tue, 25 February 2025 18:59
Как обеспечивается согласованность между двумя переходами на страницу к теме не относится. Оно нормально не будет работать ни в блокировочнике, ни в версионнике.
... и мы опять плавно переходим к тому, что постраничную выдачу может делать клиент.
Получив от сервера весь набор данных и разбивая его на куски нужного размера любых подходящим способом.
Ага. Получил клиент 10 миллионов записей, засосал их в память и отдаёт. Преееекрасно... Особенно когда в этих 10 лямах изменят одну, и их надо будет закачать заново.
Re: Ненужные сканы записей при rows [сообщение #5939 является ответом на сообщение #5938] Wed, 26 February 2025 09:27 Переход к предыдущему сообщениюПереход к следующему сообщению
pastor в настоящее время не в онлайне  pastor
Сообщений: 95
Зарегистрирован: June 2022
Географическое положение: Калуга
Member
sim_84 писал(а) Wed, 26 February 2025 09:23

Ага. Получил клиент 10 миллионов записей, засосал их в память и отдаёт. Преееекрасно... Особенно когда в этих 10 лямах изменят одну, и их надо будет закачать заново.
а если вставят, или, не дай бок, удалят?

10 млн с пейджингом - завсегда идут лесом
Re: Ненужные сканы записей при rows [сообщение #5940 является ответом на сообщение #5938] Wed, 26 February 2025 10:05 Переход к предыдущему сообщениюПереход к следующему сообщению
basid в настоящее время не в онлайне  basid
Сообщений: 174
Зарегистрирован: June 2022
Географическое положение: Asia/Irkutsk
Senior Member
sim_84 писал(а) Wed, 26 February 2025 14:23
Преееекрасно... Особенно когда в этих 10 лямах изменят одну, и их надо будет закачать заново.
Если клиент постранично выдаёт часто меняющийся набор данных, то это уже не лечится при любом способе разбивки.
Тут всю систему менять надо.
Re: Ненужные сканы записей при rows [сообщение #5941 является ответом на сообщение #5940] Wed, 26 February 2025 14:51 Переход к предыдущему сообщениюПереход к следующему сообщению
kdv в настоящее время не в онлайне  kdv
Сообщений: 102
Зарегистрирован: June 2022
Senior Member
мда. это еще когда только начались приложения на Дельфи на мобилах - были жалобы, мол, "1000 записей отображаются медленно". У меня сразу возник вопрос - вы как эту тысячу записей собрались прокручивать на 5дюймовом телефоне, и вообще соображать, что в ней?
Ответа не получил...
Re: Ненужные сканы записей при rows [сообщение #5945 является ответом на сообщение #5911] Thu, 27 February 2025 20:45 Переход к предыдущему сообщениюПереход к следующему сообщению
marcodor в настоящее время не в онлайне  marcodor
Сообщений: 8
Зарегистрирован: June 2022
Junior Member
Давайте не будем обобщать. Да, безусловно, бывают случаи, когда у нас есть большой набор данных, который мы представляем клиенту в постраничном формате. Например, заказы и их статус, журналы изменения данных. Да, есть возможность фильтрации по периоду и/или другим критериям, но это по сути не решает существующую проблему. Например, я хочу отобразить заказы за март прошлого года. Даже за короткий период времени заказов может быть много.

Зачем прятаться за палец или искать обходные пути, делая вид, что виноват дизайн приложения или разработчик, если на самом деле проблема в чем-то другом. Давайте признаем, что да... проблема в оптимизаторе Firebird, можно ли ее решить или нет, давайте проанализируем.

У меня сложилось впечатление, что некоторые участники — боты или пишут только для того, чтобы заявить о своем присутствии. Как глупо создавать сессию на сервере для каждого набора результатов и позже доставлять ее клиенту. Вы когда-нибудь писали веб-приложение?

Извините, я пишу с телефона во время поездки, у меня нет кириллицы, но GTranslate отлично справился.
Re: Ненужные сканы записей при rows [сообщение #5946 является ответом на сообщение #5945] Fri, 28 February 2025 01:26 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 432
Зарегистрирован: August 2022
Senior Member
Давай в числах. "Много заказов" это сколько в мегабайтах JSON?
Re: Ненужные сканы записей при rows [сообщение #5947 является ответом на сообщение #5946] Fri, 28 February 2025 20:05 Переход к предыдущему сообщениюПереход к следующему сообщению
avp в настоящее время не в онлайне  avp
Сообщений: 85
Зарегистрирован: October 2023
Member
Я вот в вебе для показа больших датасетов вместо пайджинга использую приём infinite scroll. Получается удобно как в гриде дельфи.
Re: Ненужные сканы записей при rows [сообщение #5948 является ответом на сообщение #5941] Fri, 28 February 2025 20:10 Переход к предыдущему сообщениюПереход к следующему сообщению
avp в настоящее время не в онлайне  avp
Сообщений: 85
Зарегистрирован: October 2023
Member
kdv писал(а) Wed, 26 February 2025 14:51
мда. это еще когда только начались приложения на Дельфи на мобилах - были жалобы, мол, "1000 записей отображаются медленно". У меня сразу возник вопрос - вы как эту тысячу записей собрались прокручивать на 5дюймовом телефоне, и вообще соображать, что в ней?
Ответа не получил...
Иногда всё же нужен просмотр потенциально больших сетов. Например колонки в записях раскрашены разными цветами и юзер просматривая 1000 записей сплошняком может легко выявить какие то маркеры о ситуациях требующих пристального внимания.
Re: Ненужные сканы записей при rows [сообщение #5950 является ответом на сообщение #5948] Mon, 03 March 2025 10:07 Переход к предыдущему сообщениюПереход к следующему сообщению
sim_84 в настоящее время в онлайне  sim_84
Сообщений: 341
Зарегистрирован: June 2022
Senior Member
1000 записей это не большой набор данных. Большой это от 10000

[Обновления: Mon, 03 March 2025 10:08]

Известить модератора

Re: Ненужные сканы записей при rows [сообщение #5951 является ответом на сообщение #5950] Mon, 03 March 2025 15:35 Переход к предыдущему сообщениюПереход к следующему сообщению
SD в настоящее время не в онлайне  SD
Сообщений: 432
Зарегистрирован: August 2022
Senior Member
Даже если каждая запись по килобайту (что сильно вряд ли), это 10 мегабайт. Меньше, чем таблица стилей от веб-приложения Дискорда. Передавать такой объём по кускам - зря время терять.
Re: Ненужные сканы записей при rows [сообщение #5952 является ответом на сообщение #5951] Mon, 03 March 2025 21:03 Переход к предыдущему сообщению
sim_84 в настоящее время в онлайне  sim_84
Сообщений: 341
Зарегистрирован: June 2022
Senior Member
В формате json одна запись может быть больше 1 кбайт. Тупо за счет utf8 и имен столбцов в каждой записи. Конечно есть более компактное представление, но им редко пользуются
Предыдущая тема: Калькулятор Конфигураций для Firebird
Следующая тема: Полнотекстовый поиск для Firebird
Переход к форуму:
  


Текущее время: Tue Mar 04 00:44:49 GMT+3 2025

Общее время, затраченное на создание страницы: 0.01415 секунд