запросе, который достает только 10 строк и
Buffers: shared hit=3 в запросе, который достает 100 строк ?
Buffers hit - это абстрактная метрика вроде cost-ов, которые нельзя напрямую сравнивать?
это не абстракная величина, а вполне реальная — кол-во блоков, в которые база посмотрела обрабатывая запрос. если у вас небольшая таблица с высокой плотностью записей, то 100 строк может и на одном блоке уместиться. и большое число блоков с небольшим числом возвращённых строк бывает, когда у вас идёт Scan (любой) с фильтрацией, или же вы аггрегируете записи.
в приведенном запросе видно, что строк мало, они расположены упрядоченно скорее всего и чтение первых 10 строк затрагивает не больше блоков, чем чтение первых 100 строк
В приведённых запросах: . "WHERE id < 100" — это один проход от корня индекса до страницы (все эти записи на одной): metapage; root → leaf. . "WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9 ,10)" — десять таких проходов (да, от корня), каждое "касание" страницы, кроме metapage (потому что она действительно просматривается один раз), считается. (поправил)
тут надо “видеть” как база выполняет проверку предиката (в EXPLAIN не видно), я не знаю и в код сейчас не полезу предположу, что в первом случае, т.к. даётся массив из 10 значений, мы получаем 10 IndexAccess-es и каждый учитывается отдельно (такой внутренний NestedLoop) во втором же случае у нас идёт один RangeScan, который обращается к: MetaPage индекса, одной странице индекса и одной странице таблицы.
buffer hits - это не абстрактная метрика. Это совершенно конкретная величина - сколько страниц мы достали из shared buffers Т.е. если написано Buffers: shared hit=22 read=2 значит 22 страницы мы нашли в шаред памяти. а 2 прочитали. С тем сколько мы достали строк это напрямую не связано: нам могло понадобиться прочитать много страниц индекса, чтобы добраться до одной записи
меня смутило, что это скорее всего те же самые страница/ы, но по несколько раз. Звучит, будто достать 10 записей по id (пусть и на одной странице) может быть дольше, чем 100 подряд
а так и есть, больше операций, к большеу кол-ву блоков обращаемся. они, скорее всего, будут в кэше и разница будет малозначительной
Вообще говоря это справедливо. Ну может там не такое соотношение (10 к 100). Но обращение к странице в шаред буферах ес-но не бесплатно. Это хорошо видно по index only scan. В ноде IOS пинится 1 страница visibility map-а, по которой проверяется видимость записи. 1 страница мапа покрывает пол гига. Если табличка больше, то скорость IOS резко проседает. Если увеличить число запинненых страниц, то эту границу можно отодвинуть.
Обсуждают сегодня