Форум: "Базы";
Текущий архив: 2004.02.10;
Скачать: [xml.tar.bz2];
ВнизКак индексировать по значениям Look-Up-полей? Найти похожие ветки
← →
Aleksandr (2004-01-15 13:44) [0]В таблице есть поле типа fkLookUp тз другой таблицы. При попытке создать IndexDef на это поле и задать таблице IndexName этого IndexDef"a ругается на неверный индекс поля. Как-то вообще можно делать сортировку по ResultField"ам LookUp"ов?
← →
Johnmen (2004-01-15 13:46) [1]НИКАК.
← →
Sandman25 (2004-01-15 13:47) [2]Можно Query использовать, там сортировка возможна.
← →
Aleksandr (2004-01-15 13:49) [3]Query нельзя по условию. К файловому датасету он не умеет обращаться.
← →
Vlad (2004-01-15 13:57) [4]
> Query нельзя по условию
Религия ? :-)
← →
Плохиш_ (2004-01-15 13:57) [5]>Sandman25 © (15.01.04 13:47) [2]
По LookUp-полю?
>Aleksandr © (15.01.04 13:49) [3]
или TClientDataSet, или [1]
← →
Vlad (2004-01-15 14:02) [6]
> Плохиш_ (15.01.04 13:57) [5]
Имелось ввиду LookUp заменить на джоин в SQL запросе.
Сортировать можно по полю из полученного НД, при этом в Query ничто не мешает оставить то же LookUp поле (уж если оно необходимо)
← →
Aleksandr (2004-01-15 14:07) [7]2 Vlad :
Ахха... я несколько ранее создавал топик с ее описанием :))
2 Плохиш_:
Я и использую TClientDataSet. Именно в нем все и происходит с невозможностью сортировать.
← →
Плохиш_ (2004-01-15 14:16) [8]>Aleksandr © (15.01.04 14:07) [7]
LookUp-поля должны быть созданы в датасете, на который ссылается TDataSetProvider.
← →
Aleksandr (2004-01-15 14:24) [9]Епрст... Неужели? Счас попробуем...
← →
Aleksandr (2004-01-15 14:59) [10]Хм... не так все просто. При попытке дать IndexFieldNames он чего-то перестраивается, но явно не по сортировке. При попытке создать IndexDef и дать IndexName ругается, что поле не найдено.
← →
Плохиш_ (2004-01-15 15:04) [11]>Aleksandr © (15.01.04 14:59) [10]
На пользуйся, и чего я такой добрый сегодня
procedure TfrmOwnerList.grdInfoTitleClick(Column: TColumn);
var
lIndex: Integer;
sIndex: String;
begin
if Assigned( Column ) then
begin
sIndex := Column.FieldName + "index";
if SortDesc then sIndex := sIndex + "_desc";
if cdsInfo.IndexName = sIndex then SortDesc := not SortDesc
else SortDesc := false;
sIndex := Column.FieldName + "index";
if SortDesc then sIndex := sIndex + "_desc";
lIndex := cdsInfo.IndexDefs.IndexOf( sIndex );
if lIndex < 0 then
with cdsInfo.IndexDefs.AddIndexDef do
begin
Name := sIndex;
Fields := Column.FieldName;
Options := [ixCaseInsensitive];
if SortDesc then Options := Options + [ixDescending];
end;
cdsInfo.IndexName := sIndex;
end;
end;
← →
Aleksandr (2004-01-15 15:34) [12]Спасибо, конечно, но у меня есть уже код:
procedure TRiFieldsList.FillIndex;
var
C : TClientDataSet;
s : string;
d : string;
i : integer;
IndName : string;
Si : TRiSortedFieldsList;
begin
C:=TRiViewInfo(FOwner).DataSet;
C.IndexFieldNames:="";
C.IndexDefs.Clear;
if (FSortInfo.Count=0) then
Exit;
s:="";
d:="";
Si:=FSortInfo;
for i:=0 to Si.Count-1 do begin
if s="" then
s:=Si.Items[i].FieldName
else
s:=s+";"+SI.Items[i].FieldName;
if SI.Items[i].SortOrder=fsDesc then begin
if d="" then
d:=SI.Items[i].FieldName
else
d:=d+";"+SI.Items[i].FieldName
end
end;
if d="" then
C.IndexFieldNames:=s
else try
IndName:=s;
if Pos(";",s)<>0 then
IndName:=ReplaceString(";","_",IndName);
if d="" then
IndName:=IndName+"1"
else
IndName:=IndName+"2";
C.IndexDefs.Add(IndName,s,[]);
C.IndexDefs.Items[C.IndexDefs.Count-1].DescFields:=d;
C.IndexName:=IndName
except
on E:Exception do
RiMessage(0,h_Error,E.Message)
end
end;
В общем, проблема не в коде, а в том, чтобы заставить сортироваться LookUp"ы. И, что очень плохо, Ваш совет не прокатывает, потому что таблица может периодически работать без провайдеров, из файлов, поэтому все лукапы должны быть на ClientDataSet.
← →
Aleksandr (2004-01-15 19:16) [13]Да даже в принципе и Бог с ним, с Providerом - можно в файл пихнуть в файл кодовые поля. Гораздо больше меня смущает то, что получение данных с провайдерного датасета, имеющего LookUpные поля, дает безумные тормоза при обращении к нему. Таблица с 7000 записей, имеющая четыре Lookup"a, на клиенте открывается около двух минут. А это уже трагедия.
← →
Vlad (2004-01-15 19:19) [14]
> Aleksandr © (15.01.04 19:16) [13]
Ага, я вспомнил, это ты вместо БД ClientDataSet"ы используешь :-)
Так что, тебе вариант с Yaffil Personal не понравился ?
← →
Aleksandr (2004-01-15 19:42) [15]Мне он понравился. Но он не понравился начальнику, который решил, что понадобится слишком много времени, чтобы всю систему перевести на него (потому как программка, с коей я мучаюсь, избавляясь от древностей вроде БДЕ - лишь малая часть ее). Да и меня смутило указание в справке, что она однопоточная - а у меня 3-звенка.
← →
Vlad (2004-01-15 19:46) [16]Ну насчет однопоточности ты не прав.
Читай внимательнее :-)
http://yaffil.ibase.ru/news.htm
05.02.2002
Yaffil Personal RC2. Скачать.
1) Полная поддержка всего API (на isc_add_user и т.п. возвращает ошибку в статусе - @feature is not supported@)
2) Поддержка сервисов
3) Многопоточность
4) Требует только WinSock1 (т.е. будет запускать на голой Win95)
← →
Aleksandr (2004-01-16 11:44) [17]Ну я ведь не сам придумал. В pdf-ном юзергайде почти дословно указано, что только однопоточный вариант. Впрочем, суть не в этом, а в том, что таких трудозатрат позволить себе не могем. Есть разница - разобраться, почему так жестоко тормозит при закачке через провайдера датасета с лукапами или переписывать две большие и десяток мелких программ, затачивая их под IB.
← →
Vlad (2004-01-16 11:54) [18]
> Aleksandr © (16.01.04 11:44) [17]
> Ну я ведь не сам придумал. В pdf-ном юзергайде почти дословно
> указано, что только однопоточный вариант
Это к версии Personal не имеет отношения.
> Есть разница - разобраться, почему так жестоко тормозит
> при закачке через провайдера датасета с лукапами или переписывать
> две большие и десяток мелких программ, затачивая их под
> IB.
лукап поля (если нет индекса в подчиненной таблице) выстраиваются довольно медленно, это вполне естественно. А даже если и есть индекс, то не все компоненты (на сколько я помню) пользуют индексы при навигации по DataSet.
ИМХО, все же лучше один раз проделать большую работу и жить спокойно, чем каждый раз мучаться из-за новых проблем...
← →
Плохиш_ (2004-01-16 12:10) [19]>Aleksandr © (15.01.04 15:34) [12]
> В общем, проблема не в коде, а в том, чтобы заставить сортироваться
> LookUp"ы. И, что очень плохо, Ваш совет не прокатывает,
> потому что таблица может периодически работать без провайдеров,
> из файлов, поэтому все лукапы должны быть на ClientDataSet.
Ну сделай для отображения ещё один ClientDataSet
← →
Aleksandr (2004-01-16 12:37) [20]2 Плохиш_:
В смысле? Я сделал по Вашему совету: на сервере данных у меня файловый ClientDataSet с LookUp"ами (кстати, открывается очень быстро), к нему прицеплен провайдер, а на клиенте, в свою очередь, ClientDataSet, берущий данные через этого провайдера. В нем поля выглядят уже как fkData и сортируются очень быстро. Пик на одном единственном этапе - когда клиентский ClientdataSet эти данные закачивает - почему-то разница с просто открытием LookUpной таблицы и тем более просто таблицы совершенно кардинальная :(.
← →
Academic (2004-01-16 12:41) [21]Идея есть, но не проверял.
Что если отслеживать события на датасете и
когда прошел дропдаун переприсваивать индекс, а после выбора значения возвращать обратно. (может это глупость)
← →
Vlad (2004-01-16 12:43) [22]
> у меня файловый ClientDataSet с LookUp"ами (кстати, открывается
> очень быстро)
Ты уверен что при этом "быстром" открытии в ClientDataSet попадают все данные, а не только видимые в гриде ? :-)
Для проверки поставь FetchOnDemand = false и открой ClientDataSet
← →
Vlad (2004-01-16 12:44) [23]
> у меня файловый ClientDataSet с LookUp"ами (кстати, открывается
> очень быстро)
Ты уверен что при этом "быстром" открытии в ClientDataSet попадают все данные, а не только видимые в гриде ? :-)
Для проверки поставь FetchOnDemand = false и открой ClientDataSet
(что будет со скоростью закачки ?)
← →
JibSkeart (2004-01-16 12:49) [24]Я это обощел так сказать
запросом вывел аля лукап поля и сортирую по ним ,
НО в таком варианте будут проблемы с редактированием ,
особенно если юзаешь join ...
← →
Aleksandr (2004-01-16 12:52) [25]2 Vlad ©:
У меня FetchOnDemand итак стоит false. Поэтому уверен.
2 ibSkeart ©:
Это все о чем? К файловому Датасету запрос не сделаешь.
← →
Vlad (2004-01-16 13:06) [26]
> Aleksandr © (16.01.04 12:52) [25]
> 2 Vlad ©:
> У меня FetchOnDemand итак стоит false. Поэтому уверен.
Откуда провайдер берет данные (какой компонент ?)
← →
Aleksandr (2004-01-16 13:16) [27]2 Vlad © :
Компонент TDataSetProvider берет из TClientDataSet"a. То есть у ClientDataSet есть имя файла и более ничего.
← →
Vlad (2004-01-16 13:29) [28]Т.е. у тебя 2 ClientDataSet.
1- CDS - источник, откуда провайдер берет данные(FetchOnDemand=false)
2- CDS - приемник, куда перегружает (FetchOnDemand=false)
т.е. загрузка данных в оба ClientDataSet происходит полностью.
Если источник не имеет лукап полей, то загрузка происходит быстро.
Если источник имеет лукап поля, то загрузка происходит медленно.
Я верно понял ?
← →
Aleksandr (2004-01-16 13:35) [29]2 Vlad © :
Совершенно верно. Механизм такой - приемник получает данные, сохраняет их в файл, отключается от источника, загружает файл и далее все скроллинги/фильтрации/сортировки идут через файл. В случае обновления данных операция повторяется.
Если источник не имеет LookUp, то загрузка происходит быстро. Если LookUp формируется CDS-приемником из нескольких CDS-источников, то тоже очень быстро (правда, скроллинг по Grid почему-то медленнее). А если LookUp формируется на CDS-источнике и CDS-приемник получает их в виде обычных полей, то загрузка идет неимоверно долго. При том, что просто открытие CDS-источника все так же быстрое.
← →
Vlad (2004-01-16 13:50) [30]
> Если LookUp формируется CDS-приемником из нескольких CDS-источников,
> то тоже очень быстро (правда, скроллинг по Grid почему-то
> медленнее).
> А если LookUp формируется на CDS-источнике и CDS-приемник
> получает их в виде обычных полей, то загрузка идет неимоверно
> долго
Все это наводит на мысли, что ClientDataSet"ы все-таки загружают данные не сразу все, а порциями.
Попробуй провести эксперимент. Источник - без лукап полей (загрузка д. б. быстрая). После открытия источника сделай ClientDataSet.Last;
ClientDataSet.First;
Что будет со временем ?
← →
Aleksandr (2004-01-16 14:40) [31]Гм. Со временем все в порядке. Я же написал уже, что, получив данные, CDS-приемник отключается от источника и переходит на независимое существование. Подключение к источнику происходит вручную, то есть исключено, что приемник при скроллинге автоматом будет что-то докачивать из источника - все таблицы работают только с файлом. В файлах данные полные.
← →
Vlad (2004-01-16 15:40) [32]
> Aleksandr © (16.01.04 14:40) [31]
Нда... непонятно.
А не пробовал, Calculated-поля грузит нормально ? Просто шальная мысль посетила сделать calculated поле равное лукапному, и в приемнике грузить вместо лукапного - calculated
← →
Aleksandr (2004-01-16 16:08) [33]Хорошая мысль. Счас попробую. Я пытался сделать несколько иной вариант: на приемнике сделать лукапы и добавить калькулируемые (internalcalc, просто calculated сортировать не дает) поля, равные лукапам. На такие калькулируемые поля он при попытке сортировать не ругается, и даже чего-то пытается сортировать, но сортирует как-то не то. То есть совсем по непонятному принципу.
← →
Aleksandr (2004-01-16 16:31) [34]Увы. Тормоза те же. Интересно, а можно ли как-то на самом сервере получить "снимок" результирующего набора источника наподобие того, который получит приемник. Чтобы сравнить, с какой скоростью он на сервере получится. Может, выгоднее окажется просто готовый стрим передать при таком раскладе.
← →
Vlad (2004-01-16 17:15) [35]
> Aleksandr © (16.01.04 16:31) [34]
У тебя CDS источник и CDS приемник как я понимаю физически на разных машинах находятся, т.е. один на клиенте, другой в каком нибудь RemoteDataModule на сервере?
Если так, то попробуй на сервере ввести еще один ClientDataSet и через провайдер подключить к источнику, грузить данные с лукап-полями в него, а из него уже на клиента. Больше мыслей никаких нет :(
← →
Aleksandr (2004-01-16 17:48) [36]Да уж... спасибо за участие в сем безуспешном предприятии... :( Придется, похоже, вернуться к БДЕ.
← →
Aleksandr (2004-01-19 11:22) [37]Вот, кстати, истчо вопрос. Тормоза присутствуют при работе через провайдера. А есть способ получить "снимок" с лукапного источника, минуя провайдера? В том плане, чтобы делать "снимок", сохранять в файл, а из файла уже через другой источник получать готовые файлы?
← →
VAleksey (2004-01-19 12:24) [38]Тебе в пункте [1] бал дан верный и абсолютно полный ответ :-)).
А тормоза при таком подходе не удивительны. Было бы удивительно если бы их не было.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.02.10;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.008 c