Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 5

Автор: Odysseos
Дата сообщения: 09.03.2010 10:26
DmitryKz

Компоненты, которыми пользуетесь для доступа к БД - в исходниках? Если да, то попробуйте скомпилировать проект не с готовыми dcu, а непосредственно с исходниками, и оттрасируйте узкое место в отладчике - на чем именно "тормоза": на выполнении запроса, на выборке записей на клиента, еще на чем? Только после выяснения того, где именно "тормоза", имеет смысл говорить об оптимизации.
Автор: Cryogen2003
Дата сообщения: 09.03.2010 10:29
greenpc
Открыл хэлп, в принципе по идее, очень интересно.


Код:
When using grid mode, the data controller loads a fixed number of dataset records into memory. The number of records to be loaded depends on the GridModeBufferCount property value. A user is permitted to perform data-related operations on the loaded records only. The automatic sorting, filtering, summary calculations and smart refresh features are not supported in grid mode. These features need to be handled manually by handling the appropriate events of the data controller.

To activate grid mode, set the data controller’s GridMode property to True. This data controller mode is deactivated though when you group records within a View. In this case, the data controller switches to default data loading mode.
Автор: greenpc
Дата сообщения: 09.03.2010 10:47
Cryogen2003
как раз то что я вам сказал
Цитата:
выключенном GridMode абсолютно так же

значит гдето у вас стоит "получить все записи" queryallrecords
Автор: Cryogen2003
Дата сообщения: 09.03.2010 10:49
greenpc
Ну стало быть, если происходит то, что происходит. Значит стоит в DOA такая галочка, как я понимаю
Автор: lingus
Дата сообщения: 09.03.2010 10:52
Добрый день.
Не подскажете какой-нибудь дельфи-опенсорс-проект который можно было бы посмотреть с целью самообразования и изучения? Паттерны - построение интерфейсов - взаимосвязь модулей.
Автор: DmitryKz
Дата сообщения: 09.03.2010 10:55
Тормоза-то не всегда случаются. С одной и той же буквой на одном запуске программы выборка по фильтрации и 10 секунд может происходить. Потом с ней же на следующем запуске все мгновенно отработает. И опять же с ней же на 3-й раз - снова тормоза. Почему и трассировку сделать затруднительно. Сейчас вот спецом три раза запустил программу и с каждым символом в алфавите прогнал - тормозов нет, лишь кратенькие задержки с некоторыми символами. Судя по исходникам на выборке из БД.
Автор: AviDen
Дата сообщения: 09.03.2010 11:20

Цитата:
По поводу того, зачем удалять записи из памяти? А все очень легко - например 50000 записей при 30 столбцах в TOracleDataSet - это примерно гиг оперативной памяти.

Это что за ппц? Каждое поле у вас по 6,5 кб памяти жрёт?
Автор: Cryogen2003
Дата сообщения: 09.03.2010 11:25
AviDen
Да так уж сделан великий и могучий TDataSet, который является основой для TOracleDataSet. Там все записи идут через TObjectList. Да хотя и сам TList - еще та фигня.
Автор: AviDen
Дата сообщения: 09.03.2010 11:30
DmitryKz, если б это был не firebird, а ms sql server, я бы объяснил причину быстрой работы повторной фильтрации с тем же выражением фильтра наличием требуемых данных в кеше. Но иногда они вытесняются другими (с базой-то и другие юзеры работают!) и тогда серваку приходится запрашивать данные для фильтрации не их оперативы, а с диска. Частично решается 1) увеличением отводимой процессу сервера памяти 2) оптимизацией структуры таблицы, по которой делается поиск (кстати, я ж думаю, индекс по искомому полю-то у вас есть?)

А вообще, я бы всё делал в точности, как написал VadimLou - фильтровал хотябы от 2 (лучше 3) букв и подтягивал не более N записей, остальные - либо с задеркой, либо при попытке пользователя погулять по гриду.

Добавлено:
Cryogen2003, стандартный TDataSet НИКАК не определяет форматы хранения выбранных с сервера данных и практически не предъявляет никаких требований к их кешированию. Он вообще жестко не задаёт никаких рамок ни для каких аспектов манипулирования данными (выборка, кеширование, хранение, модификация, навигация и пр.). Всё это - прерогатива конкретного наследника.

С оракловскими БД я, к сожалению, не работал, поэтому сказать ничего определённого не могу. Но как-то я сильно сомневаюсь, чтобы там захаркодено было на каждое поле (любого типа) каждой записи выделять over 6КБ данных, ибо это попахивает маразмом. Может, имелся в виду какой-то конкретный пример?
Автор: DmitryKz
Дата сообщения: 09.03.2010 11:49
AviDen
Индекс, конечно, есть.
Я уже и сам склоняюсь к предложению подтягивать определенное кол-во записей. Но вот хотелось бы дождаться ответа уважаемого ShIvADeSt касательно некоего LookupBox'а, с которым, если верить, проблем быть не должно
Автор: greenpc
Дата сообщения: 09.03.2010 11:56
Cryogen2003
select count(*) from table
-- 773762
колонок 37
вылелено памяти 513232 кб
стандартные поля без экзотики (типа clob ...)
время выполнения 138 сек. 1 connect
Автор: Cryogen2003
Дата сообщения: 09.03.2010 12:16
AviDen
А причем тут форматы хранения данных? Я думаю что просто дело в другом, что в TDataSet все храниться как объекты, что на каждый Row свой объект, в котором куча объектов в виде колонок. В этом и проблема дикого расхода памяти.
А пример, да в принципе любой пример, попробуйте открыть хотя бы в TkbmMemDataSet огромную таблицу. И посмотрите что будет с расходом памяти.
А так, мы уже начали офтопить.

Добавлено:
greenpc
Круто
А в какой компонент все грузили? Какие настройки у этого компонента?
Автор: jonikDk
Дата сообщения: 09.03.2010 12:19

Цитата:
уважаемого ShIvADeSt касательно некоего LookupBox'а, с которым, если верить, проблем быть не должно

Lookup от девок умеет такое
Автор: AviDen
Дата сообщения: 09.03.2010 12:26
Cryogen2003, ещё раз скажу (как человек, написавший свой набор компонент для доступа к данным, в т.ч. и наследника от TDataSet), что сам TDataSet не предъявляет абсолютно никаких требований к тому, как хранить данные. Это всё решает конкретный наследник. Но и в то, что TOracleDataSet (который писался ведь неглупыми людьми) так тупо выделяет память, тоже как-то не верится.

Скорее всего, у тебя была таблица с тремя десятками строковых полей максимально возможной длины (не знаю, какое там ограничение в оракле, в сиквелле это 8КБ). Поэтому для КАЖДОГО из них в КАЖДОЙ строке выделялась память под максимально возможную длину (независимо от реального размера данных в конкретной строке/поле). Ну, понятно, это лишь предположение (хотя описанное поведение при выделении памяти как раз и меет место быть в TADODataSet'е в режиме клиентского курсора).
Автор: Cryogen2003
Дата сообщения: 09.03.2010 12:28
AviDen
Ну скажем так, все данные в приложение поступают как раз через процедуры с получаемый курсором. Возможно в этом и есть собака.
Автор: greenpc
Дата сообщения: 09.03.2010 12:28
Cryogen2003
DOA 4.1.1 D7
TOracleDataSet
настроки по умолчанию, кроме QueryAllRecords =True;
Автор: AviDen
Дата сообщения: 09.03.2010 12:32
DmitryKz, а firebird умеет делать выборку исключительно из индекса (если, напр., я выбираю поле А, с фильтром по тому же полю А и у меня при этом в таблице есть индекс по этому полю)? сиквелл - умеет, благодаря чему в ряде случаев удается сократить кол-во обращений к диску (т.к. индекс, как правило, занимает меньше страниц памяти, чем таблица)? Если нет (или в данном случае так по каким-лю причинам этого не происходит) - нужно выбросить из таблицы лишние поля, чтобы при выполении того запроса перелопачивалось меньше страниц. Ну, т.е., удалять поля не нужно, но ведь можно создать отдельную табличку, содержащую минимальный набор полей для выборки, и обращаться к ней (правда, чтогда её нужно будет синхронизировать с основной, но это легко делается триггерами).
Автор: Cryogen2003
Дата сообщения: 09.03.2010 12:34
greenpc
То есть QueryAllRecords у вас установлена в True?
Как именно данные получаются у вас? Просто через SQL или как запуск с процедуры с возвращяемый курсором?
Автор: AviDen
Дата сообщения: 09.03.2010 12:34
Cryogen2003, источник получения данных не важен, главное - формат их хранения на клиенте. Ладно, смысла продолжать обсуждение особо нет, т.к. вопрос-то не у тебя ))
Автор: greenpc
Дата сообщения: 09.03.2010 12:49
Cryogen2003
я просто привел пример сколько используется памяти датасетом
запрос через sql. QueryAllRecords =true, чтобы получить все данные.
но так стараюсь не делать. лучше получить "кусочки" по необходимости
формат полей если интерен виден при редактировании сообщения
если интересно сделаю
Цитата:
с процедуры с возвращяемый курсором

Автор: Cryogen2003
Дата сообщения: 09.03.2010 13:07
greenpc
AviDen
Кстати, ради интереса проверил сейчас. Если получать данные через просто SQL, то все активные карты банка (select count(1) from cf_import.creditcard_creditcard - count(1) - 841104) заняли в памяти (все приложение) 650951KB. Когда попытался загрузить через процедуру и курсор, то тупо комп в синий экран свалился при занятой памяти в 2 гига). Когда пользовался в прошлой году DOA 3.xx (не помню точно какой версией пользовался) было без разницы как получаешь данные (через курсор или просто SQL), то теперь в DOA 4.1.1 разница есть. Как-то очень странно все это.
Если интересует сам селект для получения данных, то вот он:
[more=Сам селект]
SELECT DISTINCT (accno), fio, absid, minplat, expno,
agreeproduct_name, agreecurc, branchname,
regionname
FROM (SELECT TO_CHAR (cc.accno) accno,
serv.getfioclient (cc.clientid) fio,
cc.absclientid absid, cc.agreeid idagree,
cc.agreecurc agreecurc,
(SELECT bl.branchname
FROM cf_import.branches_list bl
WHERE bl.branchid = cc.owid AND ROWNUM <= 1)
AS branchname,
(serv.getrefstr (13, agreeproduct)
) agreeproduct_name,
cardimport.calcsaldoonminplat
(cardimport.calckeyforaccno
(cc.accno,
cardimport.getsyncaccnoone
(2)
),
ddate
) minplat,
cardimport.calcexpnoonaccno
(cardimport.calckeyforaccno
(cc.accno,
cardimport.getsyncaccnoone
(3)
),
ddate
) expno,
serv.getregionname
(assignment.getclientregion (cc.clientid)
) AS regionname
FROM agree cc
WHERE agreetype = 2) cc
WHERE minplat > 0 AND fio IS NOT NULL
ORDER BY branchname, regionname, fio
[/more]
Автор: ShIvADeSt
Дата сообщения: 10.03.2010 02:02
DmitryKz
Контрол стандартный - DBLookupComboBox, ищет по первым буквам первое вхождение и позиционирует курсор в выборке на нем. Либо можно использовать более расширенный вариант из RxLib (JEDI имхо через чур перегружен). Так же буковки можно ввести в RxLookupEdit. Но судя по тому, что нужно Вам - обычного лукапа за глаза.
Автор: delover
Дата сообщения: 10.03.2010 13:53
Подскажите пожалуйсто. Delphi 2006, код целиком, Work персистент.

Код:
procedure TfmMain.HelpTop1Execute(Sender: TObject);
label
4;
var
My: (TPinHttpWork);
begin
goto 4;
MessageDlg('dfgdfg', mtWarning, [], 0);
4:
My := TPinHttpWork.|Create;
try
//My;
finally
My.Free;
end;
end;
Автор: greenpc
Дата сообщения: 10.03.2010 14:09
delover
а у класа TPinHttpWork
конструктор Create параметры имеет?

Цитата:
var
My: (TPinHttpWork);
а почему в скобках
Автор: volser
Дата сообщения: 10.03.2010 14:19
delover
Да странный какой то синтаксис. Без скобок компилируется.
Автор: Odysseos
Дата сообщения: 10.03.2010 14:34
delover

А вот это:


Код:
My: (TPinHttpWork);
Автор: delover
Дата сообщения: 10.03.2010 16:40
Odysseos
- спасибо. я просто всё забыл...


Код:
procedure TfmMain.FormDestroy(Sender: TObject);
var
E: TCollectionEnumerator;
P: Pointer;
begin
{
Licence :
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any kind of
application, and to alter it and redistribute it freely, subject to
the following restrictions:
1. The origin of this software must not be misrepresented, you must
not claim that you wrote the original software.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
}
E := TCollectionEnumerator.Create(ButtonGroup1.Items);
try
while E.MoveNext do TBaseButtonItem(E.Current).Action := nil;
finally
E.Free;
end;
P := @GSocketListClass;
Inc(LongWord(P), 8);
Sys.FreeAndNil(TObject(P^));
Sys.FreeAndNil(GThreadCount);
end;
Автор: delover
Дата сообщения: 10.03.2010 19:40
О.. Уже начинает получаться
Что-то типа такого же, только цифирки некоторые подправил
[no]
Код: [/no]
'//63002:2006.03.01:1:1234567890:++(01):-:-:-:-:66000.000:0:65680.000:0:65640.000:0:65820.000:0:65660.000:0:62240.000:0:59660.000:0:59440.000:0:59140.000:0:59180.000:0:59360.000:0:58880.000:0:58820.000:0:59340.000:0:59160.000:0:58860.000:0:58600.000:0:58560.000:0:58580.000:0:58620.000:0:58360.000:0:58400.000:0:58420.000:0:58880.000:0:59340.000:0:59100.000:0:58640.000:0:58960.000:0:58800.000:0:59280.000:0:58840.000:0:58580.000:0:58860.000:0:60780.000:0:58680.000:0:58860.000:0:58680.000:0:58620.000:0:58640.000:0:58300.000:0:59080.000:0:58620.000:0:58700.000:0:58440.000:0:58820.000:0:58920.000:0:58640.000:0:58780.000:0:=='
'//63002:2006.03.01:2:1234567890:++(01):-:-:-:-:28720.000:0:29120.000:0:29680.000:0:29880.000:0:30220.000:0:28840.000:0:27000.000:0:28860.000:0:27860.000:0:27260.000:0:26920.000:0:27120.000:0:26560.000:0:25720.000:0:25860.000:0:27060.000:0:27220.000:0:27320.000:0:26540.000:0:27060.000:0:27800.000:0:27360.000:0:27860.000:0:27060.000:0:27060.000:0:27240.000:0:27340.000:0:27260.000:0:28160.000:0:27440.000:0:27800.000:0:28040.000:0:27000.000:0:25880.000:0:27560.000:0:27700.000:0:27660.000:0:26740.000:0:26620.000:0:27560.000:0:26840.000:0:27320.000:0:27560.000:0:27720.000:0:27200.000:0:27900.000:0:27640.000:0:27700.000:0:=='
[no]
Автор: greenpc
Дата сообщения: 11.03.2010 07:58
delover

Цитата:
Правильно ли я коммеентарий вставляю

F1 - Comments
Автор: Man Without Face
Дата сообщения: 11.03.2010 08:59
Всем привет, есть такой вот кусочек кода (строю график), можно ли как нибудь если условие не выполняется откинуть счетчик на одну единицу назад (один день):
for j:=Trunc(cxdedReservFrom.Date) to Trunc(cxdedReservTo.Date) do begin
if (qChart2.FieldByName('rc_smenavol_volumenum').AsInteger = mproduct[i])and(trunc(qChart2.FieldByName('rc_sd_begindate').AsDateTime)=j) then begin
if cxRadioGroup1.ItemIndex = 0 then
begin //График фактического отклонения движения за смену от расчетного
mseries[dbChart1.SeriesList.Count-1].Add(qChart2.FieldByName('otklon_fakdvforsmena').AsInteger,DateToStr(j));
end
else
begin //График фактического остатка от нарастающего расчетного
mseries[dbChart1.SeriesList.Count-1].Add(qChart2.FieldByName('otklon_fakrestfromincrease').AsInteger,DateToStr(j));
end;
mseries[dbChart1.SeriesList.Count-1].SeriesColor:=qChart2.FieldByName('producttypes_color').AsInteger;
mseries[dbChart1.SeriesList.Count-1].Title:=qChart2.FieldByName('producttypes_productname').AsString + ' ('+
qChart2.FieldByName('rc_smenavol_volumenum').AsString + ' резервуар)';
qChart2.Next;
end
else
begin
//j:=j-1; ЧТО ТО ВРОДЕ ЭТОГО, НО ТАК НЕЛЬЗЯ
qChart2.Next;
end;
end;

Заранее благодарен

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

Предыдущая тема: Clipper 5


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.