Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

После апдейт SQL запросов - тормозит скроллинг [Firebird]


Страницы:   1 2

Anthony ©   (2010-12-30 00:38:00) 

Кто опытен, помогите пожалуйста разобраться в таком обстоятельстве:

DBGridEh прицепленный к DataSet (от FIBPlus), отображает примерно 92тыс.записей
В таблице 3 поля: ID (целое), FLAG (char[1]) и NUM (целое)
И вот - нужно сделать апдейт числового поля группы записей,
размещённых между теми записями, у которых FLAG - не пуст.
У каждой очередной группе записей, размещённых между записями с непустым флагом: нужно изменить поле NUM (просто в это поле записывается следующий по порядку номер - и всё).

Так вот интересный эффект,
Если эту задачу решать, просматривая в цикле сам DataSet:

iCounter := 1;
iPrevRec := 1;
DS.First;
while not DS.Eof do begin
 if DS.FieldByName('FLAG').AsString <> '' then Inc(iCounter);
   DS.Edit;
   DS.FieldByName('NUM').AsInteger := iCounter;
   DS.Post;  
   DS.Next;
end;
DS.FullRefresh;

- то после этой операции - в прицепленном к Dataset гриде записи нормально скроллируются, как и до апдейта,
но - пройти "пешком" 92тыс. записей - долго...

Тогда я переписал код, используя SQL запросы:

iCounter := 1;
iPrevRec := 1;
QueryFetch.SQL.Text := 'SELECT ID FROM TAB WHERE FLAG <> '''''
QueryFetch.ExecQuery; // - мы сразу на 1 записи...
QueryFetch.Next;
while not QueryFetch.Eof do begin  // скачем по записям с флагом
 QueryUpdate.SQL.Text := 'UPDATE TAB SET NUM = ' + IntToStr(iCounter) + 'WHERE ID >=' + IntToStr(iPrevRec) + ' AND ID < ' + QueryFetch.Fields[0].AsString;
 QueryUpdateVerses.ExecQuery; // апдейт поля NUM у группы записей
 Inc(iCounter);  // увеличили счётчик
 iPrevRec := QueryFetch.Fields[0].AsInteger; // запомнили ID для использ. в след. итерации
 QueryFetch.Next;
end;
// после цикла - апдейт последней группы, но это не важно...

Так вот - теперь собственно сам казус - почему-то после этого варианта кода - грид, отображающий эту таблицу стал просто жутко тормозить!!
Я ради интереса провёл один эксперимент: попробовал делать апдейт с помощью SQL запросов не всех записей таблицы, а только части, оказалось, чем меньше записей обновлялось,
тем меньше потом тормоза!..

Может кто-нибудь подсказать - что это за "глюк" такой?


Anthony   (2011-01-04 01:55:00) [1]


> Читать здесь: http://www.ibase.ru/ibfaq.htm#xp

Спасибо! Интересная информация.


Anthony   (2011-01-04 01:54:00) [2]


> > А какой именно файл (или файлы) с таким разрешением Вы
> предлагаете > переименовать?
> Если незнакомо, то, видимо, никакой, а иначе файл БД.

Файлы БД Firebird изначально имеют расширение .FDB
Поэтому переименовывать нечего


Amoeba_   (2011-01-01 13:49:00) [3]

Для FireBird менять расширение с gdb на fdb.


Amoeba_   (2011-01-01 13:47:00) [4]


> Anthony ©   (31.12.10 17:13) [34]
>
>
> > А о gdb, переименовать его в другое - fb, например.
>
> - думаете это может помочь? интересно...
> А какой именно файл (или файлы) с таким разрешением Вы предлагаете
> переименовать?

Должно помочь. Читать здесь: http://www.ibase.ru/ibfaq.htm#xp


Inovet   (2011-01-01 06:05:00) [5]

> [34] Anthony ©   (31.12.10 17:13)
> А какой именно файл (или файлы) с таким разрешением Вы предлагаете
> переименовать?

Если незнакомо, то, видимо, никакой, а иначе файл БД.


Anthony   (2010-12-31 17:13:00) [6]


> А о gdb, переименовать его в другое - fb, например.

- думаете это может помочь? интересно...
А какой именно файл (или файлы) с таким разрешением Вы предлагаете переименовать?


Inovet   (2010-12-31 16:48:00) [7]

> [32] Anthony ©   (31.12.10 16:27)
> - а что это: "проблема с gdb" ?
> - и как Вы предлагаете "это" проверить?

Это разное. Проверять всё кому-то у себя.
А о gdb, переименовать его в другое - fb, например.


Anthony   (2010-12-31 16:27:00) [8]


> Надо же проверять это. А не окажется ли здесь та проблема
> с расширением gdb в Windows.

- а что это: "проблема с gdb" ?
- и как Вы предлагаете "это" проверить?


Inovet   (2010-12-31 16:06:00) [9]

> [30] Anthony ©   (31.12.10 15:18)
> и пока никто такого кода тоже сюда не привёл. (Это - тоже факт!..)

Так код что ли надо давать?

> [30] Anthony ©   (31.12.10 15:18)
> > execute block тебе в помощь !
>
> Я не знаю, что такое "execute block", если можно - поясните

Так прочитать может в справке надо? Так же как и о хранимых процедурах.

> [30] Anthony ©   (31.12.10 15:18)
> Все запросы отсортированы по полю ID.

Это разве было где-то показано?

> [30] Anthony ©   (31.12.10 15:18)
> мы сразу "стоим" на первой записи этого запроса

Этого да. Но о сортировке не было сказано, вот и вывод - не известно где стоим. Сортировка по сурогатному ID тоже не понятна, ну да ладно.

> [30] Anthony ©   (31.12.10 15:18)
> И вообще, если в уже откомпилированном (EXE) коде IntToStr
> вернула всё правильно, то у заказчика она вернёт по-другому?
> Думаю, так не может быть

Зря так думаешь - это надо осознанно сделать. Да и зачем так, если можно правильно

> [30] Anthony ©   (31.12.10 15:18)
> >  Всегда нужно использовать параметры в запросах
>
> -пробовал переписать запрос, используя параметры - один
> и тот же результат...

Вот и надо оставить с параметрами. А лучше см. выше.

> [30] Anthony ©   (31.12.10 15:18)
> У меня - НЕ СЕРВЕРНЫЙ вариант приложения!

Ну и что, писать надо правильно.

По существу вопроса. Надо же проверять это. А не окажется ли здесь та проблема с расширением gdb в Windows.


Anthony   (2010-12-31 15:18:00) [10]

ОГРОМНОЕ СПАСИБО ВСЕМ, особенно благодарю Max Zyuzin за конкретность...

У меня есть новости по поводу моего вопроса, кому интересно, делюсь:
"Тормоза" прокрутки DataSet пропали только после того, как уже после окончания апдейт запросов - я переоткрыл саму базу!
Почему так происходит - не знаю, может быть это особенности или библиотеки FIBPlus или самого Firebird.

Однако, есть факи: Если делать изменения в каждой записи таблицы, крутя в цикле сам DataSet, - то после изменений (во всех 92000 записях) - "тормозов" нет. Если же делать апдейт записей SQL запросами, (естественно при этом заблокировав компоненты просмотра DataSet.DisableControls) - то после окончания операции - DataSet жутко тормозит.

Пробовал вообще отключать DataSet от базы на время прохождения запросов - не помогает... Потом вот уже тупо в конце кода поставил:
Database.Close;
Database.Open;
- после чего скроллинг пошел снова без тормозов.

Не знаю, наверно причина где-то глубоко и в силу малого опыта я в этом механизме не разберусь, поэтому буду использовать просто изменения записей Dataseta в цикле, и всё...
Тем более, оказалось, что этот метод оказался по скорости НЕ МЕДЛЕННЕЕ, чем SQL апдейты! (У меня - НЕ СЕРВЕРНЫЙ вариант приложения!)
Возможно конечно, что эту операцию можно как-то быстро сделать одним запросом, но сам я не знаю как, и пока никто такого кода тоже сюда не привёл. (Это - тоже факт!..)


> execute block тебе в помощь !

Я не знаю, что такое "execute block", если можно - поясните


> ему понадобиться больше суток что бы их тупо просмотреть.

- да, так и есть, эту таблицу записей пользователь помечал примерно 2 недели


> Функция IntToStr(iPrevRec) - при разных региональных настройках
> может вернуть разный разделитель целого и дробного

- не понял... Разве целое число iPrevRec - имеет дробную часть?
И вообще, если в уже откомпилированном (EXE) коде IntToStr вернула всё правильно, то у заказчика она вернёт по-другому? Думаю, так не может быть


> Почему Вы решили, что этот запрос вам вернет НД в таком,
>  же порядке, как его просматривал пользователь?

Все запросы отсортированы по полю ID.
А вообще - это замечание - тоже не касается сути моего вопроса... Ну и что - если мой запрос на апдейт - был (бы) составлен неверно, и записал в поле NUM не то, что надо, суть вопроса то не в этом!! Если бы я запросом - просто обнулил поле NUM у всех записей, потом - всё равно начинаются "тормоза", я проверял


>  Всегда нужно использовать параметры в запросах

-пробовал переписать запрос, используя параметры - один и тот же результат...


> 3. Вообще из примера мне не ясно как оно работает.
> QueryFetch.SQL.Text := 'SELECT ID FROM TAB WHERE FLAG <> '''''
> QueryFetch.ExecQuery; // - мы сразу на 1 записи...

- работает очень просто: после выполнения запроса - в QueryFetch оказываются все записи с ненулевым полем FLAG, и + к этому (по умолчанию) - мы сразу "стоим" на первой записи этого запроса. А потом - начинаем фетчить в цикле его записи, и всё.


Виталий Панасенко   (2010-12-31 09:30:00) [11]


> > куча мелких запросов - много медленнее, чем ОДИН "большой
>
> > запрос
>
> - а Вы сначала попробуйте написать это одним запросом!..
>


> Anthony ©   (31.12.10 00:04) [20]

execute block тебе в помощь !


Max Zyuzin   (2010-12-31 09:17:00) [12]

1. Я вот сильно сомневаюсь, что пользователь в состоянии просмотреть глазками и принять решения касательно 92000 записей одновременно. Банально посчитав что на принятие решения ему нужна 1 сек. ему понадобиться больше суток что бы их тупо просмотреть.
2. Всегда нужно использовать параметры в запросах. Оно конечно к делу не относится, но может здорово нагадить
Строка типа
QueryUpdate.SQL.Text := 'UPDATE TAB SET NUM = ' + IntToStr(iCounter) + 'WHERE ID >=' + IntToStr(iPrevRec) + ' AND ID < ' + QueryFetch.Fields[0].AsString;
очень неправильна по своей сути. Функция IntToStr(iPrevRec) - при разных региональных настройках может вернуть разный разделитель целого и дробного - и ваша программа просто перестанет выполняться. Если вы таким способом будете передавать например дату, то вообще будет "весело".

3. Вообще из примера мне не ясно как оно работает.
QueryFetch.SQL.Text := 'SELECT ID FROM TAB WHERE FLAG <> '''''
QueryFetch.ExecQuery; // - мы сразу на 1 записи...

Почему Вы решили, что этот запрос вам вернет НД в таком, же порядке, как его просматривал пользователь?
В вашем "зависающем" примере мне не ясно, какой датасет отображается в DBGridEh? В первом примере это, я так понимаю DS.

4. Вам предложили выше по ветке массу вариантов: От применения одного запроса, до отключения контролов, дабы не мешали. Вы что нибудь из этого попробовали?
5. В вашей теме уже 27 ответов, а вы по какой то причине обвиняете тех, кто пытается вам помочь, в том, что они за вас не хотят все сделать. Это нехорошо.


sniknik   (2010-12-31 08:28:00) [13]

> Никто даже близко не ответил, почему у DataSet могли бы начаться тормоза...
вот это вот позиция начинающего... "спец" ищет проблему у себя в коде в первую очередь (ну, скоре просто не допустит подобного, т.к. не делает странного), а начинающий в датасетах, виндовс, и т.д., только не у себя...
т.е. один делает программу на том что есть, под систему, другой пишет абы как и ожидает, что система поймет.

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

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


Германн   (2010-12-31 02:50:00) [14]


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

Ну это ищи в "социальных сетях". А не на профессиональном форуме.

> когда задающий на форуме вопрос по уровню может дать фору
> многим

И пальцы "растопыривай" тоже там. Мы пока не увидели "форы". Равно как и "уровня".
Или найми специалиста, если есть возможность ему заплатить.


Anthony   (2010-12-31 02:24:00) [15]


> http://www.gunsmoker.ru/2008/10/x-y-z.html

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


Германн   (2010-12-31 01:44:00) [16]


> Если бы я знал суть ПРОБЛЕМЫ а не вопроса, тогда да, вопроса
> бы не было

http://www.gunsmoker.ru/2008/10/x-y-z.html


> И ещё: мастера Delhi - вы перевели мой вопрос в категорию
> "Начинающим" - почему?

Только модератор может перенести вопрос в другую конференцию. И не надо его спрашивать "почему".


Anthony   (2010-12-31 01:38:00) [17]


> если бы ты знал в чем суть, вопроса бы не было.

- не согласен. Если бы я знал суть ПРОБЛЕМЫ а не вопроса, тогда да, вопроса бы не было. А я сказал - что подсказывающие не поняли СУТЬ ВОПРОСА.


> ПОКАЗЫВАЙ ВСЕ КАК ЕСТЬ, БЕЗ ДЕЛЕНИЙ НА "ЭТО ПОКАЖУ, А ЭТО
> К ВОПРОСУ НЕ ОТНОСИТСЯ".

- глюк имеет место быть именно в том коде, что я привёл.


> > Разве такой код можно написать, чтобы он работал быстрее?
> вот этот можно.

- а это вообще про что? У меня вопрос про тормознутость DataSet, после того как по нему прошлись апдейт-запросами, а не про скорость работы...

И ещё: мастера Delhi - вы перевели мой вопрос в категорию "Начинающим" - почему?..
Никто даже близко не ответил, почему у DataSet могли бы начаться тормоза... Вы думаете - если Вы как "спецы" не смогли разобраться что к чему - "Начинающие" помогут?


sniknik   (2010-12-31 00:44:00) [18]

> - можно более понятным языком, очём идёт речь?
могу только на примере ADO, "твоих" фибов не знаю.
но вообще кеш он и в Африке кеш... смысл один, работаешь с данными в одном месте (на клиенте) после скидываешь результат в другое (сервер). а не так как ты пытаешься (и ради чего? просто впихнуть запросы т.к. круто? или чего? они у тебя как самоцель) промежуточные результаты сохраняешь на сервер, а для показа на клиенте делаешь после пере запрос только что отправленных данных.

> а сама суть вопроса осталась никем не затронутой.
если бы ты знал в чем суть, вопроса бы не было. поэтому всегда ПОКАЗЫВАЙ ВСЕ КАК ЕСТЬ, БЕЗ ДЕЛЕНИЙ НА "ЭТО ПОКАЖУ, А ЭТО К ВОПРОСУ НЕ ОТНОСИТСЯ".
чтобы решать, что относится, а что нет нужно знать ответ.

> - в какой подсказке говорилось про "параметры"?
http://www.delphimaster.ru/cgi-bin/forum.pl?n=18&id=1293575440
Inovet ©   (29.12.10 18:07) [10]
> А какие ещё "параметры надо"?
> Разве такой код можно написать, чтобы он работал быстрее?
вот этот можно.


Anatoly Podgoretsky   (2010-12-31 00:10:00) [19]


> они - вообще никакого отношения НЕ имеют к моему вопросу,
>  только зря насчёт них "копья ломали", а сама суть вопроса
> осталась никем не затронутой.


Позволь нам судить имеют или нет.


Anthony   (2010-12-31 00:04:00) [20]


> UPDATE TAB SET NUM = NUM+1 WHERE FLAG<>''

Это Вам после шампанского пришло в голову или после фуршета? )))
Сами проанализируйте - что делает Ваш запрос...


> вариант с кешированными изменениями лучше...

- можно более понятным языком, очём идёт речь?


> куча мелких запросов - много медленнее, чем ОДИН "большой
> запрос

- а Вы сначала попробуйте написать это одним запросом!..


> QueryUpdateVerses.ExecQuery; //??? пере запрос чего?  говорил
> вроде что туже самую таблицу правишь... а тут + Verses

- посмотрите [1] - я допустил в примере кода ошибку и сразу поправился, Вы наверно просто не обратили внимание...


> Я так понял, что пользователь, просматривая записи "отмечает"
> "пограничные" записи а не сразу всю группу?

- да, правильно Вы поняли. Пользователь просматривает текстовое поле у всех 92000 записей, делая пометки, из которых потом получаются группы.
Автоматизировать эту операцию нельзя, потому что признаки новой группы в тексте специфичны и понятны только человеку...


> Где там у тебя никого не интересует, здесь оперируем только приведеным кодом.

- это Вы про Disable.Controls ?
Может я не сумел донести вопрос... Зависания прокрутки грида - а точнее - это тормоза самого DataSeta у меня начинаются НЕ во время SQL запросов, а ПОСЛЕ всего апдейта, поэтому я и не написал этих строк в коде, они -
вообще никакого отношения НЕ имеют к моему вопросу, только зря насчёт них "копья ломали", а сама суть вопроса осталась никем не затронутой.


>  //про параметры тебе уже говорили. опять не "обратил внимания"?

- в какой подсказке говорилось про "параметры"? Простите - не увидел, поясните пожалуйста, что имеете ввиду...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо