Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.12.2013, 05:45   #1
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию Ускорить чтение из базы

Здравствуйте!
В общем есть база (mdb), объем ~50 мб (окала 20000 позиций).
Во время работы программы, иногда, приходится обращаться к БД (только для чтения).

Формирую SQL запрос в ADOQuery, затем активирую его и считываю необходимые данные, затем деактивирую, формирую новый запрос и снова активирую.
Все это в цикле.

Так вот, допустим 500 объектам, которые таким образом получают данные из БД (1 запрос для 1 объекта), для этого требуется больше времени, чем например, загрузить и отобразить текстуру.

Если не обращаться к базе, то весь цикл отработает быстрее чем за секунду.
Если же обращаться к базе, то весь цикл отработает за 10-20 секунд.

Сам SQL запрос не очень большой:
Код:
SELECT [Прайс 1].Наценка, [Прайс скидок 1].Скидка, [All].* 
FROM [Прайс 1],[Прайс скидок 1], [All] 
WHERE ([Прайс 1].Код=[All].Код and [Прайс скидок 1].Код=[All].Код) and [All].[Тип] like "%В%" and [All].Положение like "%\9\%"
ORDER BY [All].Код;
Причем основное время занимает: QueryALL.Active:=True;
Даже если после активации ничего не считывать, и переходить к следующему элементу цикла, то время за которое он отработает - не на много сократится, в лучшем случае секунды на 2.

Вот я и подумал, может есть какая-нибудь возможность ускорить этот процесс?

Подскажите как быть, может сам SQL запрос как-нибудь оптимизировать или я что-то не совсем так делаю.
Заранее спасибо!

Последний раз редактировалось ZBEP; 19.12.2013 в 11:23.
ZBEP вне форума Ответить с цитированием
Старый 19.12.2013, 07:09   #2
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

а так?
Код:
SELECT [Прайс 1].Наценка, [Прайс скидок 1].Скидка, [All].*
FROM [All]
LEFT JOIN [Прайс 1] ON [Прайс 1].Код=[All].Код
LEFT JOIN [Прайс скидок 1] ON [Прайс скидок 1].Код=[All].Код
WHERE [All].[Тип] like "%В%" and [All].Положение like "%\9\%"
ORDER BY [All].Код
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 19.12.2013, 08:44   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Формирую SQL запрос в ADOQuery, затем активирую его и считываю необходимые данные, затем деактивирую, формирую новый запрос и снова активирую.
Все это в цикле.
И это в цикле 500 раз? Переделай логику - вытащи один раз все нужное из базы. Не обязательно одним запросом, можно в разные ADOQuery двумя-тремя запросами. 50Мб не так уж много
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 19.12.2013, 09:06   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

+1. я полностью, на 146% согласен с мнением Аватар!
Я хотел сказать тоже самое, но не мог сформулировать!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.12.2013, 10:50   #5
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

Аватар, Serge_Bliznykov, дело в том, что "величина" цикла тоже варьируется и нечто подобное я сделал, но если цикл более 500.
Для больших циклах - актуально, но когда необходимо получить разовую позицию, либо небольшой цикл, то из-за величины базы, предложенный Вами метод наоборот может замедлить работу (например если необходимые записи расположены где-то в конце, то пока дойдет до 20000 записи, 500 раз с ручной проверкой нужных данных - пройдут те же 15 секунд).

Еще заметил, что для старого, слабенького компа, разделитель типа получения данных в 500 объектов был более-менее оптимальным.
А для нового, этот параметр можно снизить скорее до 40-60.
Т.е. если менее 60 объектов, то используется метод описанный выше (который работает почти так же, одинаково долго на обоих машинах), иначе используется предложенный Вами метод.

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

О, а насчет этого:
Цитата:
Не обязательно одним запросом, можно в разные ADOQuery двумя-тремя запросами. 50Мб не так уж много
Как-то не подумал, спасибо, попробую.

Slym, сейчас проверю.

Последний раз редактировалось ZBEP; 19.12.2013 в 10:54.
ZBEP вне форума Ответить с цитированием
Старый 19.12.2013, 11:02   #6
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

лайки надо выбрасывать, по возможности, они тормозят
eval вне форума Ответить с цитированием
Старый 19.12.2013, 11:12   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Если напрямую в ADOQuery искать запись простым перебором или даже с помощью Locate, то может достаточно долго получиться. Но если использовать тот же ADOQuery в связке с ClientDataSet например и создать в нем нужные клиентские индексы, то поиск в ClientDataSet по FindKey по скорости практически не зависит от физического расположения информации в датасете
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 19.12.2013, 11:17   #8
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

eval, знаю, но есть какая-нибудь альтернатива?
Просто в базе, есть столбцы, в которых вписан массив данных (типа: \1\23\645\..\n\ ), если не использовать лайки, то позже придется использовать "pos()", либо разбивать запись c помощью StringReplace в StringList и в цикле проверять наличие искомого номера.

pos - еще тормознутее, как и разбивка с перебором, в данном случае.
ZBEP вне форума Ответить с цитированием
Старый 19.12.2013, 11:19   #9
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

Аватар, про ClientDataSet, не знал, спасибо!
Буду пробовать!
ZBEP вне форума Ответить с цитированием
Старый 19.12.2013, 11:22   #10
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

надо знать что к чему, может изначально (при внесении данных) в отдельные поля скидывать В и 9, а может еще чего. так только гадание
eval вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение данных из базы Access из ресурса Аватар БД в Delphi 9 27.06.2013 16:42
Запись и чтение WAV-файлов в/из базы Sanprof БД в Delphi 1 15.11.2010 13:27
Как сделать чтение из тяжелой базы данных? Sanek777 Общие вопросы Delphi 1 02.09.2008 23:51
Чтение из базы Антон Шестаков БД в Delphi 8 18.05.2007 19:24