[SQL] придумать хитрую конструкцию
От: sushko Россия  
Дата: 05.09.18 09:21
Оценка:
У меня есть таблица в БД с 50,000 13-значных номеров дисконтных карт клиентов, эти номера идут, вообще говоря, не подряд, т.е. могут быть большие пропуски. Этот список грузится в программу очень долго(10+ минут) из-за хреновой связи между клиентом и сервером. Хочется предоставить клиенту возможность выбрать:

— грузить номера 2100000000001 — 2100000001000
— грузить номера 2100000001001 — 2100000002000
— и так далее.

Помогите придумать на SQL конструкцию типа "отсортируй номера по возрастанию и дай мне каждый тысячный номер из списка"?

P.S. Базы данных — FireBird и SQLite.
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Отредактировано 05.09.2018 9:21 sushko . Предыдущая версия .
Re: [SQL] придумать хитрую конструкцию
От: BlackEric http://black-eric.lj.ru
Дата: 05.09.18 10:20
Оценка:
Здравствуйте, sushko, Вы писали:

S>- грузить номера 2100000000001 — 2100000001000

S>- грузить номера 2100000001001 — 2100000002000
S>- и так далее.

S>Помогите придумать на SQL конструкцию типа "отсортируй номера по возрастанию и дай мне каждый тысячный номер из списка"?


S>P.S. Базы данных — FireBird и SQLite.


Select distinct substring(number, 10) from table
order by substring(number, 10)
https://github.com/BlackEric001
Re[2]: [SQL] придумать хитрую конструкцию
От: sushko Россия  
Дата: 05.09.18 10:41
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Select distinct substring(number, 10) from table

BE>order by substring(number, 10)

Ага, точно, не подумал... Не совсем то, что хотелось (при больших пропусках будут разное к-во номеров в разных результатах), но намного, намного лучше, чем ничего!

А еще других идей нет?
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[3]: [SQL] придумать хитрую конструкцию
От: BlackEric http://black-eric.lj.ru
Дата: 05.09.18 11:57
Оценка:
Здравствуйте, sushko, Вы писали:

S>А еще других идей нет?


Сделать отдельную табличку диапазонов. Ну и выборки between.
А вообще — 50000 записей зазиповать и даже через мобильный интернет не должно быть проблемой.
https://github.com/BlackEric001
Re[4]: [SQL] придумать хитрую конструкцию
От: sushko Россия  
Дата: 05.09.18 12:58
Оценка:
Здравствуйте, BlackEric, Вы писали:

S>>А еще других идей нет?

BE>Сделать отдельную табличку диапазонов. Ну и выборки between.

Да, это понятно, но хоочется все сделать красиво — без оверхеда в виде доптаблицы

BE>А вообще — 50000 записей зазиповать и даже через мобильный интернет не должно быть проблемой.


А как их зиповать, если передачей занимается драйвер FB через VPN? Я ж сам между клиентом и сервером влезть не могу...
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re: [SQL] придумать хитрую конструкцию
От: DmitryMS  
Дата: 05.09.18 13:07
Оценка:
Для подобных задач есть специализорванный механизм, называется window functions, на твоих базах, вроде как, работает. Кайф обламывать не буду — гугли сам. Идея такая, что ты можешь брать или пропускать какое то количество записей с текущей, что RDBMS без куросора не очень то давали делать раньше.
Re[2]: [SQL] придумать хитрую конструкцию
От: DmitryMS  
Дата: 05.09.18 14:04
Оценка:
Если не пойдет с оконными функциями, можно попробовать партишнинг — сортируешь записи, делишь на 1000 и берешь целую часть, не округляя, потом выводишь ренджи для каждой партиции.
Re: [SQL] придумать хитрую конструкцию
От: Ромашка Украина  
Дата: 05.09.18 19:19
Оценка: 5 (1) +1
Здравствуйте, sushko, Вы писали:
S>Помогите придумать на SQL конструкцию типа "отсортируй номера по возрастанию и дай мне каждый тысячный номер из списка"?
S>P.S. Базы данных — FireBird и SQLite.

Тебе это нужно?
для firebird (sqllite гугли сам)

select first 1000 skip 0 * from blablabla order by blablabla
select first 1000 skip 1000 * from blablabla order by blablabla
select first 1000 skip 2000 * from blablabla order by blablabla


Всё, что нас не убивает, ещё горько об этом пожалеет.
Re: [SQL] придумать хитрую конструкцию
От: vsb Казахстан  
Дата: 05.09.18 19:32
Оценка: +1
Здравствуйте, sushko, Вы писали:

S>У меня есть таблица в БД с 50,000 13-значных номеров дисконтных карт клиентов, эти номера идут, вообще говоря, не подряд, т.е. могут быть большие пропуски. Этот список грузится в программу очень долго(10+ минут) из-за хреновой связи между клиентом и сервером. Хочется предоставить клиенту возможность выбрать:


S>- грузить номера 2100000000001 — 2100000001000

S>- грузить номера 2100000001001 — 2100000002000
S>- и так далее.

S>Помогите придумать на SQL конструкцию типа "отсортируй номера по возрастанию и дай мне каждый тысячный номер из списка"?


S>P.S. Базы данных — FireBird и SQLite.


В оракле примерно так:

select num from (
  select num, row_number() rn
  from numbers
  order by num)
where rn % 1000 = 1


то бишь сделать внутренний запрос со счётчиком и отфильтровать каждую тысячную запись.
Re[2]: [SQL] придумать хитрую конструкцию
От: sushko Россия  
Дата: 06.09.18 06:48
Оценка:
Здравствуйте, Ромашка, Вы писали:

Р>
Р>select first 1000 skip 0 * from blablabla order by blablabla
Р>


Гм, не знаю... Это поможет получить тысячную строчку, но как получить двухтысячную? Пулять еще один запрос? Дорого получится....

P.S. Для SQLite нашел аналог: SELECT ... LIMIT... OFFSET...
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[3]: [SQL] придумать хитрую конструкцию
От: Ромашка Украина  
Дата: 06.09.18 07:17
Оценка:
Здравствуйте, sushko, Вы писали:
S>Гм, не знаю... Это поможет получить тысячную строчку, но как получить двухтысячную? Пулять еще один запрос? Дорого получится....

Это для другого — это для возможности порционной загрузки данных. Чтобы не обломалось на длинном запросе. В этом случае тебе особо неинтересно, какой номер на 2000й или 5000й позиции — загрузится тогда и посмотрим.

Есть решение твоей задачи "в лоб" — с 3.0 в FB есть функция row_number(). Но я бы не советовал, это как-то через одно место.
Извини, нет под рукой fb, поэтому псевдокод:

select *
from table
where row_number(over by id) % 1000 = 0


Всё, что нас не убивает, ещё горько об этом пожалеет.
Re[4]: [SQL] придумать хитрую конструкцию
От: sushko Россия  
Дата: 06.09.18 07:24
Оценка:
Здравствуйте, Ромашка, Вы писали:

Р>Есть решение твоей задачи "в лоб" — с 3.0 в FB есть функция row_number(). Но я бы не советовал, это как-то через одно место.


Да, я видел, спасибо, но у меня FB 2.5 Поискал, как добавить row_number в мой FB, но оно как-то не очень работает...
Бесплатный генератор отчетов для программ на C/C++
http://www.oxetta.com
Re[5]: [SQL] придумать хитрую конструкцию
От: LuciferNovoros Россия  
Дата: 06.09.18 10:49
Оценка:
Здравствуйте, sushko, Вы писали:

S>Да, я видел, спасибо, но у меня FB 2.5 Поискал, как добавить row_number в мой FB, но оно как-то не очень работает...


Я как-то решал подобную задачу. Только там прайсы выгружались с товарами. После мучений с порциями, окнами и прочими извратами, решил просто: процедура на сервере выгружает XML, который упаковывается и выкладывается на закачку клиентами. Клиенты смотрят на файл, если его версия поменялась — тянут к себе, распаковывают и заливают в SQLite. В итоге эта схема работает уже года три, клиентов примерно около сотни. Нареканий нет.
Re[6]: [SQL] придумать хитрую конструкцию
От: BlackEric http://black-eric.lj.ru
Дата: 06.09.18 12:05
Оценка:
Здравствуйте, LuciferNovoros, Вы писали:

LN>Я как-то решал подобную задачу. Только там прайсы выгружались с товарами. После мучений с порциями, окнами и прочими извратами, решил просто: процедура на сервере выгружает XML, который упаковывается и выкладывается на закачку клиентами. Клиенты смотрят на файл, если его версия поменялась — тянут к себе, распаковывают и заливают в SQLite. В итоге эта схема работает уже года три, клиентов примерно около сотни. Нареканий нет.


А если в JSON и 7zip, то будет еще компактнее.
https://github.com/BlackEric001
Re[7]: [SQL] придумать хитрую конструкцию
От: LuciferNovoros Россия  
Дата: 06.09.18 12:13
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>А если в JSON и 7zip, то будет еще компактнее.


Я в то время json еще готовить не умел. А по XML были готовые наработки в FB еще с версии 1.0
Re: [SQL] придумать хитрую конструкцию
От: vmpire Россия  
Дата: 06.09.18 13:42
Оценка:
Здравствуйте, sushko, Вы писали:

S>У меня есть таблица в БД с 50,000 13-значных номеров дисконтных карт клиентов, эти номера идут, вообще говоря, не подряд, т.е. могут быть большие пропуски. Этот список грузится в программу очень долго(10+ минут) из-за хреновой связи между клиентом и сервером.

50000*13/10/60 = 1083 б/с
Что, действительно НАСТОЛЬКО медленно? Может, тормоза из-за чего-то другого?

S>Помогите придумать на SQL конструкцию типа "отсортируй номера по возрастанию и дай мне каждый тысячный номер из списка"?

А первичного автоинкрементного ключа на эту таблицу нет?
Если есть, то, можно его сделать и использовать вместо row_number.
Строго говоря это не будет эквивалентно, но для данной задачи подойдёт.
Re[3]: [SQL] придумать хитрую конструкцию
От: vsb Казахстан  
Дата: 06.09.18 14:16
Оценка:
Здравствуйте, sushko, Вы писали:

S>P.S. Для SQLite нашел аналог: SELECT ... LIMIT... OFFSET...


offset это не очень хороший вариант, т.к. он всегда выполняет запрос и просто пробегается по всем записям отбрасывая их. Для полной загрузки сложность будет квадратичная от числа порций. То бишь ты загружаешь 9 порцию, база будет пробегаться по первым 8-ми порциям отбрасывая их. Загружаешь 10-ю порцию, база будет пробегаться по первым 9-ти порциям отбрасывая их. Твой исходный вариант с num between from and to куда лучше, т.к. (конечно при наличии индекса) база его отработает куда быстрей. Впрочем если записей немного, то проблем особых с limit не будет, какая разница, будет запрос отдаваться миллисекунду или 10 миллисекунд.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.