Как лучше решить задачу
Модератор: kdv
Как лучше решить задачу
Имеется база данных на Interbase 2009 (программирую на Delphi 2007). Как ограничить SQL запрос по количеству записей, т.е. имеется основная таблица 700 - 800 тыс. строк (в разных месяцах по разному) у неё есть подчинённые таблицы. Отчёт формируется около 3 часов. Хочу разбить формирование отчёта на части и каждую часть выполнять в отдельном потоке. Если делить таблицу по содержимому полей (столбцов) потоки получаются сильно разные по времени выполнения. Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
Пробовал перед отчётом добавлять уникальное поле и по нему разбивать по потокам, потом соединять получившиеся текстовые файлы в один. Время формирования отчёта сокращается до 15 минут, но проблема в том, что реестр (отчёт) должен быть в одном TXT файле и просортирован особым образом. Не представляю, как можно сортировать текстовый файл.
Пробовал перед отчётом добавлять уникальное поле и по нему разбивать по потокам, потом соединять получившиеся текстовые файлы в один. Время формирования отчёта сокращается до 15 минут, но проблема в том, что реестр (отчёт) должен быть в одном TXT файле и просортирован особым образом. Не представляю, как можно сортировать текстовый файл.
Re: Как лучше решить задачу
см. langref.pdf про select в части ограничителя ROWS. Правда, это ограничитель выбираемых записей, а не обсчитываемых, и обязательно должен быть с ORDER BY.Как ограничить SQL запрос по количеству записей
значит, причина не в количестве выбираемых записей, а в количестве обрабатываемых. И улучшать производительность такого нужно при помощи SQL и индексов, а не ROWS.Отчёт формируется около 3 часов.
imho это ерунда. еще рекомендую посмотреть, одни и те же данные вы обрабатываете в отчете, или все время новые. Если одни и те же, может, имеет смысл заранее подготовить и сохранять агрегируемые значения?Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
Re: Как лучше решить задачу
Спасибо, понял.kdv писал(а):Например, первый поток выполняет запрос, ограниченный с 1 по 100 тыс. порядковую запись, второй поток с 100 тыс.+1 порядковой записи по 200 тыс. и так далее.
imho это ерунда.
Давно подумываю, как бы создать единую сеть с филиалами и что бы все работали с моей программой и забыли про DOS и DBF... Проблема в большом количестве уникальных данных...kdv писал(а):значит, причина не в количестве выбираемых записей, а в количестве обрабатываемых. И улучшать производительность такого нужно при помощи SQL и индексов, а не ROWS.
Количество и размер запросов и таблиц уже оптимизированно по максимуму (на большее моих мозгов не хватит)...
Идея была нагрузить компьютер на постоянно 100%, не на плавающие от 15% до 80%.
Тему можно закрывать.
Re: Как лучше решить задачу
большом - это каком? база сколько десятков гиг?Проблема в большом количестве уникальных данных...
значит учиться нужно. все нужные индексы есть? планы запросов нормальные? статистика по индексам пересобирается?Количество и размер запросов и таблиц уже оптимизированно по максимуму (на большее моих мозгов не хватит)...
не очень понятен смысл. вообще 100% загрузка означает, что какая-то задача грузит процессор на 100%, и быстрее выполняться уже не может (если не менять процессор на более быстрый). СУБД, кстати, больше с диском работает, чем с процессором, поэтому и не должна во всех случаях грузить процессор на 100%.Идея была нагрузить компьютер на постоянно 100%
Re: Как лучше решить задачу
kdv писал(а):большом - это каком? база сколько десятков гиг?
В филиалах своими силами и с помощью своей программы (написана на Clippere, может знакомы с программой "Белый медведь") формируют от одной до двадцати таблиц DBF в каждом филиале и привозят мне. Размер таблиц небольшой 10-50МБ каждой, большое количество записей. Все справочные коды свои, уникальный индекс состоит из 4-6 полей, много опечаток, сокращения слов...kdv писал(а):не очень понятен смысл. вообще 100% загрузка означает, что какая-то задача грузит процессор на 100%, и быстрее выполняться уже не может (если не менять процессор на более быстрый). СУБД, кстати, больше с диском работает, чем с процессором, поэтому и не должна во всех случаях грузить процессор на 100%.
Мной разработан алгоритм, по которому выполняется загрузка из DBF в таблицу Interbase, на этом этапе каждая запись уникальна. Следующий алгоритм в цикле проходит таблицу и пытается распознать данные и перенести их в нужное место основной базы данных...
До 2008 года использовался вариант предусмотренный программой "Белый медведь" (частично автоматизированный) который занимал от 3 до 4 суток.
Экспериментально определил, что больше 20 потоков уже не приводят к сокращению общего времени работы моей программы. Основной принцип работы программы поисковые сопоставления. До сегодняшнего дня не удавалось равномерно нагружать потоки (один ещё работает, а другой уже выполнился и простаивает). Конечно, я понимаю, что это попахивает мазохизмом, когда многоядерный процессор визуально напрягается как одноядерный...
Re: Как лучше решить задачу
P.S. Додумался. RecNo номер текущей записи, если сделать присвоение IBQuery1.RecNo:= указываем номер записи, который получаем делением RecordCount на количество желаемых потоков. Негде не читал, что такое присвоение пройдёт... Как говорится "Хорошая мысля, приходит опосля".
Re: Как лучше решить задачу
RecordCount содержит количество считанных на текущий момент записей с сервера. Считали одну запись из миллиона - будет 1, а не миллион.который получаем делением RecordCount на количество желаемых потоков.
p.s. вы, похоже, сами с собой разговариваете. я так и не получил ответ, о какого рода объемах БД InterBase идет речь. Кстати, если это не "отчет", а обработка, то ничего не имею против обработки "в потоках". Нужно только помнить правило - 1 коннект на 1 поток (thread).
И вообще - сначала отчеты, потом обработка.... Определяйтесь уже
Re: Как лучше решить задачу
IBQuery1.Last;kdv писал(а):RecordCount содержит количество считанных на текущий момент записей с сервера. Считали одну запись из миллиона - будет 1, а не миллион.
На текущий момент база Interbase почти 1.2 Гб. Поначалу сильно увеличивалась, сейчас почти не растёт (50-100 Мб в месяц).kdv писал(а):p.s. вы, похоже, сами с собой разговариваете. я так и не получил ответ, о какого рода объемах БД InterBase идет речь. Кстати, если это не "отчет", а обработка, то ничего не имею против обработки "в потоках". Нужно только помнить правило - 1 коннект на 1 поток (thread).
И вообще - сначала отчеты, потом обработка.... Определяйтесь уже
Программа состоит из одной формы, на которой расположена одна кнопка и прогресс выполнения. Входные таблицы записываются в определённые каталоги. Вывод из программы: текстовый файл (электронный носитель) 10-15 Мб и Excel распечатка на бумагу в сжатом формате.
Меня вообще-то интересовало как получить быстрый доступ к порядковому номеру записи, поисками занимался не постоянно, а как приспичит.
Получил Ваш ответ и смерился (пусть будет как есть). И почти сразу пришла мысль (а можно попробовать так) и все получилось.
Так что спасибо Вам, если бы не Вы, то так бы у меня не чего и не получилось бы.
Re: Как лучше решить задачу
это приведет к фетчу всех записей выборки на клиента, чего вы так старательно пытаетесь избежать.IBQuery1.Last;
Вы бы лучше почитали мою статью http://www.ibase.ru/devinfo/ibx.htm
детский размер. я серьезно.На текущий момент база Interbase почти 1.2 Гб.
порядковый номер записи есть только на клиенте, после того как эта запись выбрана с сервера. На сервере "порядковых номеров" не существует. там только первичные ключи.как получить быстрый доступ к порядковому номеру записи
Re: Как лучше решить задачу
Моя задача как программиста написать программу, чтобы она выполняла в существующих условиях то, что требуется в кратчайшее время и с меньшими затратами ... Взрослеешь после того как начинаешь делать соответствующие поступки, а не после достижения определённого размера который окружающими будет считаться приемлемым...