Как лучше решить задачу

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Как лучше решить задачу

Сообщение Vavan » 30 окт 2011, 20:24

Имеется база данных на Interbase 2009 (программирую на Delphi 2007). Как ограничить SQL запрос по количеству записей, т.е. имеется основная таблица 700 - 800 тыс. строк (в разных месяцах по разному) у неё есть подчинённые таблицы. Отчёт формируется около 3 часов. Хочу разбить формирование отчёта на части и каждую часть выполнять в отдельном потоке. Если делить таблицу по содержимому полей (столбцов) потоки получаются сильно разные по времени выполнения. Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
Пробовал перед отчётом добавлять уникальное поле и по нему разбивать по потокам, потом соединять получившиеся текстовые файлы в один. Время формирования отчёта сокращается до 15 минут, но проблема в том, что реестр (отчёт) должен быть в одном TXT файле и просортирован особым образом. Не представляю, как можно сортировать текстовый файл.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Как лучше решить задачу

Сообщение kdv » 30 окт 2011, 21:55

Как ограничить SQL запрос по количеству записей
см. langref.pdf про select в части ограничителя ROWS. Правда, это ограничитель выбираемых записей, а не обсчитываемых, и обязательно должен быть с ORDER BY.
Отчёт формируется около 3 часов.
значит, причина не в количестве выбираемых записей, а в количестве обрабатываемых. И улучшать производительность такого нужно при помощи SQL и индексов, а не ROWS.
Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
imho это ерунда. еще рекомендую посмотреть, одни и те же данные вы обрабатываете в отчете, или все время новые. Если одни и те же, может, имеет смысл заранее подготовить и сохранять агрегируемые значения?

Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Re: Как лучше решить задачу

Сообщение Vavan » 30 окт 2011, 23:47

kdv писал(а):Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
imho это ерунда.
Спасибо, понял.
kdv писал(а):значит, причина не в количестве выбираемых записей, а в количестве обрабатываемых. И улучшать производительность такого нужно при помощи SQL и индексов, а не ROWS.
Давно подумываю, как бы создать единую сеть с филиалами и что бы все работали с моей программой и забыли про DOS и DBF... Проблема в большом количестве уникальных данных...
Количество и размер запросов и таблиц уже оптимизированно по максимуму (на большее моих мозгов не хватит)...
Идея была нагрузить компьютер на постоянно 100%, не на плавающие от 15% до 80%.
Тему можно закрывать.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Как лучше решить задачу

Сообщение kdv » 31 окт 2011, 02:49

Проблема в большом количестве уникальных данных...
большом - это каком? база сколько десятков гиг?
Количество и размер запросов и таблиц уже оптимизированно по максимуму (на большее моих мозгов не хватит)...
значит учиться нужно. все нужные индексы есть? планы запросов нормальные? статистика по индексам пересобирается?
Идея была нагрузить компьютер на постоянно 100%
не очень понятен смысл. вообще 100% загрузка означает, что какая-то задача грузит процессор на 100%, и быстрее выполняться уже не может (если не менять процессор на более быстрый). СУБД, кстати, больше с диском работает, чем с процессором, поэтому и не должна во всех случаях грузить процессор на 100%.

Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Re: Как лучше решить задачу

Сообщение Vavan » 31 окт 2011, 06:37

kdv писал(а):большом - это каком? база сколько десятков гиг?
kdv писал(а):не очень понятен смысл. вообще 100% загрузка означает, что какая-то задача грузит процессор на 100%, и быстрее выполняться уже не может (если не менять процессор на более быстрый). СУБД, кстати, больше с диском работает, чем с процессором, поэтому и не должна во всех случаях грузить процессор на 100%.
В филиалах своими силами и с помощью своей программы (написана на Clippere, может знакомы с программой "Белый медведь") формируют от одной до двадцати таблиц DBF в каждом филиале и привозят мне. Размер таблиц небольшой 10-50МБ каждой, большое количество записей. Все справочные коды свои, уникальный индекс состоит из 4-6 полей, много опечаток, сокращения слов...
Мной разработан алгоритм, по которому выполняется загрузка из DBF в таблицу Interbase, на этом этапе каждая запись уникальна. Следующий алгоритм в цикле проходит таблицу и пытается распознать данные и перенести их в нужное место основной базы данных...
До 2008 года использовался вариант предусмотренный программой "Белый медведь" (частично автоматизированный) который занимал от 3 до 4 суток.
Экспериментально определил, что больше 20 потоков уже не приводят к сокращению общего времени работы моей программы. Основной принцип работы программы поисковые сопоставления. До сегодняшнего дня не удавалось равномерно нагружать потоки (один ещё работает, а другой уже выполнился и простаивает). Конечно, я понимаю, что это попахивает мазохизмом, когда многоядерный процессор визуально напрягается как одноядерный...

Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Re: Как лучше решить задачу

Сообщение Vavan » 31 окт 2011, 06:41

P.S. Додумался. RecNo номер текущей записи, если сделать присвоение IBQuery1.RecNo:= указываем номер записи, который получаем делением RecordCount на количество желаемых потоков. Негде не читал, что такое присвоение пройдёт... Как говорится "Хорошая мысля, приходит опосля".

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Как лучше решить задачу

Сообщение kdv » 31 окт 2011, 12:29

который получаем делением RecordCount на количество желаемых потоков.
RecordCount содержит количество считанных на текущий момент записей с сервера. Считали одну запись из миллиона - будет 1, а не миллион.

p.s. вы, похоже, сами с собой разговариваете. я так и не получил ответ, о какого рода объемах БД InterBase идет речь. Кстати, если это не "отчет", а обработка, то ничего не имею против обработки "в потоках". Нужно только помнить правило - 1 коннект на 1 поток (thread).
И вообще - сначала отчеты, потом обработка.... Определяйтесь уже :-)

Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Re: Как лучше решить задачу

Сообщение Vavan » 31 окт 2011, 14:55

kdv писал(а):RecordCount содержит количество считанных на текущий момент записей с сервера. Считали одну запись из миллиона - будет 1, а не миллион.
IBQuery1.Last;
kdv писал(а):p.s. вы, похоже, сами с собой разговариваете. я так и не получил ответ, о какого рода объемах БД InterBase идет речь. Кстати, если это не "отчет", а обработка, то ничего не имею против обработки "в потоках". Нужно только помнить правило - 1 коннект на 1 поток (thread).
И вообще - сначала отчеты, потом обработка.... Определяйтесь уже
На текущий момент база Interbase почти 1.2 Гб. Поначалу сильно увеличивалась, сейчас почти не растёт (50-100 Мб в месяц).
Программа состоит из одной формы, на которой расположена одна кнопка и прогресс выполнения. Входные таблицы записываются в определённые каталоги. Вывод из программы: текстовый файл (электронный носитель) 10-15 Мб и Excel распечатка на бумагу в сжатом формате.
Меня вообще-то интересовало как получить быстрый доступ к порядковому номеру записи, поисками занимался не постоянно, а как приспичит.
Получил Ваш ответ и смерился (пусть будет как есть). И почти сразу пришла мысль (а можно попробовать так) и все получилось.
Так что спасибо Вам, если бы не Вы, то так бы у меня не чего и не получилось бы.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Как лучше решить задачу

Сообщение kdv » 31 окт 2011, 19:22

IBQuery1.Last;
это приведет к фетчу всех записей выборки на клиента, чего вы так старательно пытаетесь избежать.
Вы бы лучше почитали мою статью http://www.ibase.ru/devinfo/ibx.htm
На текущий момент база Interbase почти 1.2 Гб.
детский размер. я серьезно.
как получить быстрый доступ к порядковому номеру записи
порядковый номер записи есть только на клиенте, после того как эта запись выбрана с сервера. На сервере "порядковых номеров" не существует. там только первичные ключи.

Vavan
Сообщения: 6
Зарегистрирован: 30 окт 2011, 19:22

Re: Как лучше решить задачу

Сообщение Vavan » 01 ноя 2011, 06:31

Моя задача как программиста написать программу, чтобы она выполняла в существующих условиях то, что требуется в кратчайшее время и с меньшими затратами :!: ... Взрослеешь после того как начинаешь делать соответствующие поступки, а не после достижения определённого размера который окружающими будет считаться приемлемым... :?:

Ответить