Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
imissyouso
Member

Откуда:
Сообщений: 5
Привет!
На самом деле, это один из вопросов на интервью в компанию, которая занимается хайлоадом.
Например, есть таблица размером 1TB с первичным b-tree ключем по id. Нам нужно сделать селект по рейджу id >= 5000 and id < 10000000. Мы не должны заблокировать всю базу. База под высокой нагрузкой.
Имеет ли смысл разбивать такой select запрос на много маленьких?
select * from a where id > =5000 and id < 10000;
select * from a where id >= 10000 and id < 15000;
...

Если да, то почему? Чем это объясняется? Какие могут быть еще техники решения этой задачи?
Спасибо.
27 июн 20, 16:23    [22158265]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3675
imissyouso
Привет!
На самом деле, это один из вопросов на интервью в компанию, которая занимается хайлоадом.
Например, есть таблица размером 1TB с первичным b-tree ключем по id. Нам нужно сделать селект по рейджу id >= 5000 and id < 10000000. Мы не должны заблокировать всю базу. База под высокой нагрузкой.
Имеет ли смысл разбивать такой select запрос на много маленьких?
select * from a where id > =5000 and id < 10000;
select * from a where id >= 10000 and id < 15000;
...

Если да, то почему? Чем это объясняется? Какие могут быть еще техники решения этой задачи?
Спасибо.


"селект по рейджу"

Что такое "рейджу"?
28 июн 20, 17:56    [22158627]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
mefman
Member

Откуда:
Сообщений: 2979
Заблокировать селектом?
28 июн 20, 18:40    [22158645]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 8656
mefman
Заблокировать селектом?

Селект что-то блокирует ?
(в том виде, как приведено в первом сообщении)
28 июн 20, 18:43    [22158646]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 8656
Если под "заблокировать" понимается "поставить колом" дисковую подсистему на сервере, то это наверное лечится банальным уменьшение скорости "забирания" данных или нормальным железом/OS/прямыми_руками_админов. Уменьшить скорость "забирания" можно:
банальным sleep после fetch'а на клиенте
ограничить скорости сети (наверное могут сделать админы) до конкретного клиента
ограничить скорости процессор/диск конкретного процесса postgres на сервере (х.з. как определить, какой процесс ограничивать)
и 100500 резных других способов которые можно придумать в меру своих фантазий

В Oracle для таких целей есть Oracle Database Resource Manager, есть ли аналогичные средства в PostgreSQL - не знаю.

Бить один SELECT на несколько - лично я смысла не вижу.

IMHO
28 июн 20, 18:55    [22158650]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Алексей Роза
Member

Откуда: РФ
Сообщений: 426
imissyouso
select *

меня это смущает... а куда селект то? это в HTML будут выводить? тогда не надо!
кому и зачем понадобилось 10 лямов строк со всеми колонками?!
на загруженной базе...
это как не разбивай, всё равно будет нагрузка.

Сообщение было отредактировано: 28 июн 20, 21:09
28 июн 20, 21:10    [22158676]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
bochkov
Member

Откуда: Камчатка
Сообщений: 4079
imissyouso
Привет!
На самом деле, это один из вопросов на интервью в компанию, которая занимается хайлоадом.
Например, есть таблица размером 1TB с первичным b-tree ключем по id. Нам нужно сделать селект по рейджу id >= 5000 and id < 10000000. Мы не должны заблокировать всю базу. База под высокой нагрузкой.
Имеет ли смысл разбивать такой select запрос на много маленьких?
select * from a where id > =5000 and id < 10000;
select * from a where id >= 10000 and id < 15000;
...

Если да, то почему? Чем это объясняется? Какие могут быть еще техники решения этой задачи?
Спасибо.

1 это очень много данных, извлекаться они будут долго, в это время нагрузка на сервер как правило будет максимальна,
плюс к этому, сервером будут выполнятся другие запросы, поэтому надо разбивать один запрос на тысячи, быть может миллионы запросов, между запросами будут паузы, тем самым сервер будет разгружен и выполнять запросы от других процессов,
2 множество запросов наверняка позволит избежать создания временных таблиц (в этом случае временная таблица вряд ли будет создаваться, но так часто бывает с сложными запросами)
3 обычно такая выгрузка влечет последующие обработки и быстрая выдача данных из маленьких запросов позволит сразу же начать эти вычисления
4 postgresql такой огромный запрос не заблокирует таблицу, но другие СУБД например Mysql, может вызвать блокировку на несколько дней (было у меня такое)
PS и как показывает практика, извлечение много данных маленькими запросами, но в несколько потоков, происходит на много быстрее чем один огромный селект

Сообщение было отредактировано: 29 июн 20, 04:34
29 июн 20, 04:27    [22158753]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
mefman
Member

Откуда:
Сообщений: 2979
bochkov,
Про mvcc не надо забывать
29 июн 20, 09:59    [22158837]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
imissyouso
Member

Откуда:
Сообщений: 5
Ролг Хупин
"селект по рейджу"

Что такое "рейджу"?

рейнджу* = range

bochkov
postgresql такой огромный запрос не заблокирует таблицу, но другие СУБД например Mysql, может вызвать блокировку на несколько дней (было у меня такое)

и как решали эту проблему в mysql? в мускуле это случается потому что там нет mvcc? Он вынужден блокировать каждую строку по отдельности?

bochkov
1 это очень много данных, извлекаться они будут долго, в это время нагрузка на сервер как правило будет максимальна,
плюс к этому, сервером будут выполнятся другие запросы, поэтому надо разбивать один запрос на тысячи, быть может миллионы запросов, между запросами будут паузы, тем самым сервер будет разгружен и выполнять запросы от других процессов,

но ведь можно выставить каждому клиенту свой приоритет, чтобы не отжирал все ресурсы и не забирал их у других клиентов, плюс у каждого запроса свой определенный буфферный кэш, который по размеру не равен вообще всему кэшу системы. Вопрос в том как это сделать, может есть здесь знатоки.

Алексей Роза
меня это смущает... а куда селект то? это в HTML будут выводить? тогда не надо!
кому и зачем понадобилось 10 лямов строк со всеми колонками?!
на загруженной базе...
это как не разбивай, всё равно будет нагрузка.

да никуда, просто очень абстрактная задача, представим что раз в год кому-то понадобилось выгрузить много данных

Leonid Kudryavtsev
Бить один SELECT на несколько - лично я смысла не вижу.

ну как минимум в postgres'e

Сообщение было отредактировано: 29 июн 20, 11:12
29 июн 20, 11:13    [22158890]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
mefman
Member

Откуда:
Сообщений: 2979
imissyouso

Leonid Kudryavtsev
Бить один SELECT на несколько - лично я смысла не вижу.

ну как минимум в postgres'e

А начиная с 9.6 есть параллелизм, как минимум для последовательных чтений.
29 июн 20, 11:17    [22158893]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Алексей Роза
Member

Откуда: РФ
Сообщений: 426
imissyouso
да никуда, просто очень абстрактная задача, представим что раз в год кому-то понадобилось выгрузить много данных

ну и пусть ночью выгружает.
или "заказ данных", когда в бэкграунде создаётся файлик и выкладывается куда-то.
29 июн 20, 12:23    [22158978]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
bochkov
Member

Откуда: Камчатка
Сообщений: 4079
автор
bochkov
postgresql такой огромный запрос не заблокирует таблицу, но другие СУБД например Mysql, может вызвать блокировку на несколько дней (было у меня такое)

и как решали эту проблему в mysql? в мускуле это случается потому что там нет mvcc? Он вынужден блокировать каждую строку по отдельности?

mysql блокирует таблицу пока insert(update) не пройдет
select делается паралельно
но если очередь запросов будет типа
долгий select, insert, потом select и еще select ... все selectы после insert , будут ждать пока insert не дождется выполнения первого запроса, которым долго извлекаются данные

для mysql проблема решается в твоем случае
select * from a where id=5000
select * from a where id=5001
select * from a where id=5002
select * from a where id=5003
...
select * from a where id=10000000

обычно такие выборки происходят ETL средствами, которые позволяют объединить результат, обработать, ну и подготовить данные для отчета

автор
bochkov
1 это очень много данных, извлекаться они будут долго, в это время нагрузка на сервер как правило будет максимальна,
плюс к этому, сервером будут выполнятся другие запросы, поэтому надо разбивать один запрос на тысячи, быть может миллионы запросов, между запросами будут паузы, тем самым сервер будет разгружен и выполнять запросы от других процессов,

но ведь можно выставить каждому клиенту свой приоритет, чтобы не отжирал все ресурсы и не забирал их у других клиентов, плюс у каждого запроса свой определенный буфферный кэш, который по размеру не равен вообще всему кэшу системы. Вопрос в том как это сделать, может есть здесь знатоки.

можно наверное, этим не занимался,
сервак не твоя собственность, как правило ты даже не админ (а даже если и админ, тут надо быть очень осторожным и долго подумать), и те приложения которые берут оттуда данные написаны давно и даже не тобой и должны работать быстро, как прежде, и твоя выгрузка юзерам не должна портить настроение

автор
Leonid Kudryavtsev
Бить один SELECT на несколько - лично я смысла не вижу.

ну как минимум в postgres'e

если запрос более разумного ожидания,
то надо бить, потому что твои изделия будут ложить сервер
29 июн 20, 12:38    [22158988]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
bochkov
Member

Откуда: Камчатка
Сообщений: 4079
Алексей Роза
imissyouso
да никуда, просто очень абстрактная задача, представим что раз в год кому-то понадобилось выгрузить много данных

ну и пусть ночью выгружает.
или "заказ данных", когда в бэкграунде создаётся файлик и выкладывается куда-то.

это если ночью сервер простаивает
29 июн 20, 12:40    [22158990]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 8656
bochkov

mysql блокирует таблицу пока insert(update) не пройдет
select делается паралельно
но если очередь запросов будет типа
долгий select, insert, потом select и еще select ... все selectы после insert , будут ждать пока insert не дождется выполнения первого запроса, которым долго извлекаются данные

Жесть какая. Как-то даже не верится. Т.к. что бы сделать такую однопоточную хрень (с блокировкой таблицы при INSERT), это нужно быть на первом курсе ПТУ. Т.к. даже на втором курсе, даже после полбутылки водки, такую ахинею спроектировать крайне сложно

IMHO

P.S.Хотя, при должном профессионализме, и Oracle можно колом поставить. Например наплодив в OLTP системе Bitmap индексов.
P.P.S. Бегло посмотрел доку по InnoDB, даже специальный тип блокировки есть "Insert Intention Locks" и "AUTO-INC Locks", ни про какое "блокирует таблицу" документация не упоминает (хотя AUTO-INC Locks и "is a special table-level lock" как он может мешать SELECT'ам, лично мне не понятно).
29 июн 20, 15:51    [22159136]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 8656
https://wiki.postgresql.org/wiki/Priorities
https://pgxn.org/dist/prioritize/

Если железо более-менее нормальное и пользователей много, то снижение приоритета на CPU -> вероятно автоматически приведет и к снижению read нагрузки на IO.

Разумеется, в ситуации когда на сервере один HDD и полтора пользователя, то снижай / не снижай - сильно большой разницы не заметишь.

IMHO & AFAIK
29 июн 20, 17:21    [22159177]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1080
Leonid Kudryavtsev
bochkov

mysql блокирует таблицу пока insert(update) не пройдет
select делается паралельно
но если очередь запросов будет типа
долгий select, insert, потом select и еще select ... все selectы после insert , будут ждать пока insert не дождется выполнения первого запроса, которым долго извлекаются данные

Жесть какая. Как-то даже не верится. Т.к. что бы сделать такую однопоточную хрень (с блокировкой таблицы при INSERT), это нужно быть на первом курсе ПТУ. Т.к. даже на втором курсе, даже после полбутылки водки, такую ахинею спроектировать крайне сложно

Это наверняка про myisam говорилось, а не про mysql.
29 июн 20, 17:35    [22159183]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
Shweik
Member

Откуда:
Сообщений: 1598
Алексей Роза
imissyouso
select *

меня это смущает... а куда селект то? это в HTML будут выводить? тогда не надо!
кому и зачем понадобилось 10 лямов строк со всеми колонками?!
на загруженной базе...
это как не разбивай, всё равно будет нагрузка.

Думаю это фильтр для отбраковки тех, кто оставит звёздочку и не задаст вопроса "какие поля нужны". Сурово, но ведь это же "хайлоад" ;-)
1 июл 20, 06:24    [22160055]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
mefman
Member

Откуда:
Сообщений: 2979
Имеет ли смысл разбивать себе голову на много маленьких?
1 июл 20, 15:47    [22160223]     Ответить | Цитировать Сообщить модератору
 Re: Имеет ли смысл разбивать большой select запрос на много маленьких?  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 283
mefman,

Если есть сомнения, то нужно протестировать 2-8 вариантов и сравнить скорость работы, хотя бы на локальной машине.
Иногда случаются парадоксы - то что хорошо работает в одном случае - ужасно работает в другом случае, хотя код и суть примерно одинаковая. Уж не знаю почему, но отличия по времени могут достигать 2 раз, при этом нагрузка примерно одинаковая.

В вашем случае вообще непонятно, зачем 10 млн строк?
Для того, чтобы переварить такой запрос железо должно быть не хилым и ДА, такой запрос подвесит вашу базу данных.

.
Если же вы анализируете БД и хотите сделать какие то аналитические выборки/исследования, то лучше делать это кусками.
Будет и быстрее и нагрузки меньше.
.
2 июл 20, 15:31    [22160992]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить