Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
7-29623
Alexandr3
2003-11-23 04:11
2004.02.10
Epson opos help


4-29676
FBI
2003-12-08 13:48
2004.02.10
Подбор


3-29211
Y_Andrey
2004-01-19 22:22
2004.02.10
Добавить ProgressBar к Locate


14-29556
NeyroSpace
2004-01-20 18:36
2004.02.10
CM_TEXTCHANGED


1-29305
Sam Stone
2004-01-28 11:54
2004.02.10
Dll ка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский