Страница 1 из 2

FibPlus 6.4.1 установка курсора на нужную запись

Добавлено: 13 июл 2006, 21:53
paratruper
Есть таблица примерно 400000 записей использую pFIBDataSet в режиме ограниченного кеша. Как оптимально и быстро сделать позиционирование на необходимую запись. Использую метод Locate но он очень медленный, возвращает результат примерно через 25-30 сек, При использовании метода ExtLocate результат практически мгновенный но работает только с первыми 20 записями таблицы, если же искомое значение находиться в следующих записях всегда возвращает отрицательный результат. При этом если переместить вручную (ползункои на гриде) курсор в конец таблицы, то результат даже не возвращаеться а пишеться can't read record 120 (буфер стоит на 120 записей). Добавлю что перед поиском всегда происходит переоткрытие pFIBDataSet (таковы условия задачи).Возможно ли как-то решить мою проблему, либо это у меня руки кривые? Если можно ткните в пример.
Железо : атлон 3000+, 512 озу, сата 80 гб.
p.s. Devrace.com не работает уже 2 дня .... :(

Добавлено: 13 июл 2006, 22:06
Merlin
Природу не наобманЁшь. Насчёт фокусов с кешем в плюсах я не копенгаген, ибо от лукавого это всё. Но прокручивать по каждому чиху поллимона записей - это таки варварство. Помедитируй над разумным усечением выборки при помощи дополнительных условий в кляузе Where. Ну не нужны пользователю каждый раз все поллимона, не нужны. А судя по постановке, может и вообще нужна одна-единственная. Вот условия её поиска, по которым делаешь Locate, тогда и зафигачить в Where. А если таки не одна, а разумное подмножество, то должны быть и дополнительные условия, характеризующие это подмножество.

Добавлено: 14 июл 2006, 00:17
paratruper
Так ведь проблема то в том и состоит что действительно пользователю видеть много записей и не надо, хватит минимума, к примеру 120 :) НО! если искомая запись находитья в конце таблицы, а текущая выборка показывает её начало, то locate сделаный в этот самый момент идёт оооочень долго.
Как вариант можно конечно сделать select * from table where field=условие, который выплюнет в датасет допустим 100 записей из которых 2 искомые, а 98 просто чтоб заполнить грид :), однако, честно скажу по природе я немного ленивый :) и если это как-то реализуеться в компонентах за которые я заплатил, то зачем над этим думать:) Хотя если это никак не реализовать средствами Фибов Придеться выкручиваться с помощью select * from table where field.

Добавлено: 14 июл 2006, 01:56
CyberMax
Дело тут не в FIB+... Не забывай, что табличная и реляционная архитектуры - разные. И подход к ним нужен разный. Если в первой вытягивать все записи - нормальный режим работы, то во второй - это маразм. Где-то читал, что если пользователю отображается больше 100 записей в сетке, это повод задуматься над ограничением выборки. И дело не столько в скорости выборки, сколько в скорости передачи и отображения (что мы видим на твоем примере). Короче, читай мат. часть. Конкретно - про реляционные СУБД.

Добавлено: 14 июл 2006, 02:24
paratruper
Я понимаю что маразм сливать на клиента все записи сразу, эта проблема решается с помощью ограничения кеша у фибов, вернее перевод их(фибов) в режим ограниченного кеша. Косячок идет когда ищется запись которая находиться не в той выборке которая была запрошена клиентом, причем ищется фибовским методом extlocate. Потому как если искать обычным locate то ооооочень долго идет поиск(такое чувство что он фетчит всю таблицу).
Я возможно непонятно выражаю свой вопрос, поэтому повторюсь - есть ли способ заставить фибы БЫСТРО найти запись, вернее даже не столько найти сколько БЫСТРО СПОЗИЦИОНИРОВАТЬ КУРСОР на необходимую мне запись в таблице, в режиме работы с ограниченным кешем.
Пока как вариант вижу тупо делать выборку select* from table where где условия задавать в таком виде что бы на выходе был пакет записей включающий в себя интересующую меня запись, но тут придется увязывать этот массив с гридом, то есть корректно отображать его с установкой курсора на необходимую мне запись. А это все - время, которое можно потратить на другие вещи :). Поэтому я и спросил, может как-то фибы настроить нужно чтобы они в режиме ограниченного кеша правильно и быстро позиционировали курсор на необходимую мне запись.
Хотя если есть ещё какой либо вариант решения моей проблемы буду рад услышать.
К сожалению на даный момент супорт у фибов сломался, а куда ещё обратиться - не знаю.

Добавлено: 14 июл 2006, 03:04
CyberMax
Я же тебе сказал - это не проблема FIB+! :evil: :evil: :evil:
Пока как вариант вижу тупо делать выборку select* from table where где условия задавать в таком виде что бы на выходе был пакет записей включающий в себя интересующую меня запись
Это не тупо, это так и должно быть. Только не пакет, а конкретная запись.

Насчет поиска Locate. Напиши алгоритм, который без индекса должен искать запись среди 400 000? Готов побиться об заклад, что это будет перебор с первой записи до конечной. Отсюда и фетч всей таблицы, если запись находится в конце.А теперь подумай, почему FIB+ должен работать БЫСТРО, если именно это ему приходится делать? Или у него развитой алгоритм угадывания?

Добавлено: 14 июл 2006, 07:53
paratruper
На счёт locate и неиндексированного поиска понял, спасибо. Буду думать как сделать правильное позиционирование с помощью select'a, потому что необходимо визуализировать не только одну запись на которой должен стоять курсор но и остальные 19 (грид на 20записей) , потому что запрос всегда будет возвращать одну запись (по условиям задачи) , а пользователю надо создать иллюзию непрерывной таблицы(грида).
Или это тоже не совсем корректно?

Добавлено: 14 июл 2006, 08:05
CyberMax
paratruper писал(а):необходимо визуализировать не только одну запись на которой должен стоять курсор но и остальные 19 (грид на 20записей) , потому что запрос всегда будет возвращать одну запись (по условиям задачи) , а пользователю надо создать иллюзию непрерывной таблицы(грида).
Или это тоже не совсем корректно?
Да. Вот смотри, как сделано в базе по нашим абонентам. При выборе справочника абонентов, сразу открывается форма фильтрации. Я ввожу лицевой счет, жму "ОК" и в сетке, естественно, оказывается одна запись. Вот с ней-то я уже и работаю. F3 - одна форма, F4 - другая т.д.
Зачем делать лишние телодвижения, что-то там имитируя...

Добавлено: 14 июл 2006, 10:14
paratruper
У меня немного другая задача. Есть общий список клиентов, и есть список клиентов которые должны к примеру денег, причем данные должников все есть в общем списке, соответственно на каждый список свой грид. Так вот вся моя проблема заключаеться в том что при выборе клиента из списка(щелчка мышой по строке грида) должников, хотелось бы чтобы в общем списке клиентов курсор становился на соответсвующую запись. Locate решает эту задачу идеально, но медленно. Тепрь вот думаю как прикрутить механизм с select'ами. может ещё какой нибудь вариант есть?

Добавлено: 14 июл 2006, 12:28
Ivan_Pisarevsky
Жара у вас в Белоруси? тогда ясно, коллега, Вы перегрелись...

Чтоб найти одно вшивого должника Вы выкачиваете на клиента 400 тыщ записей... а завтра их будет мильён... :shock:

Юзер задав отбор только должников и найдя своего подопечного в списке УЖЕ ВСЕ сделал, должник уже найден!!! теперь вопрос, нахрена бедолаге попадать в грид 400 тыщами записей? Бр...
В упор не вижу смысла во всех этих дурацких манипуляциях.

Итак есть список контрагентов, один из возможных критериев фильтрации - отбор должников. Вот и сделай одну форму с гридом, по кнопочке отрывается другая форма с кучей чекбоксов/радиобаттонов с условиями отбора, юзер осмыслил чего он хочет видеть, жмакает соответствующие пимпочки, потом "ОК" и видит основную формочку с гридом, где, например, в строке состояния написано "фильтеред". А в это время, когда юзер нажал "ОК" ты динамически формируешь SQL запрос и пихаешь его в датасет.

Добавлено: 14 июл 2006, 14:34
paratruper
Ну да жарковато у нас.. :)
В том-то все и дело что НЕ СЛИВАЮ Я ВСЕ ЗАПИСИ НА КЛИЕНТА, если бы сливал то вопросов таких бы не задавал, locate'om в кеше искал бы да и все. А так приходиться лить на клиента по 100 записей, и если искомая запись не в слитом диапазоне locate долго работает.
Изначально у меня была мысль что у фибов предусмотрена какая нибудь возможность быстрого перехода и установки курсора на необходимую запись, но что-то не могу найти. Теперь посидел... подумал... буду делать через запросы.
В общем спасибо всем. Буду запросы составлять :)

p.s. ВСЕ ЗАПИСИ НА КЛИЕНТА НЕ СЛИВАЮ... :):):) и сливать не буду :)

Добавлено: 14 июл 2006, 15:00
Merlin
paratruper писал(а): В том-то все и дело что НЕ СЛИВАЮ Я ВСЕ ЗАПИСИ НА КЛИЕНТА,
Щаз. Именно это ты делаешь, когда запускаешь Locate.
paratruper писал(а): если бы сливал то вопросов таких бы не задавал, locate'om в кеше искал бы да и все.
А в кеше они откуда возьмуццо? От сырости?
paratruper писал(а): А так приходиться лить на клиента по 100 записей, и если искомая запись не в слитом диапазоне locate долго работает.
Удивительно, правда? :-D Этот режим ограниченного кеша - либо форсированный фетч заданного количества записей при опен (так-то компонент только одну фетчит, если не присоединён к гриду, который форсирует фетч для заполнения одного экрана), либо ещё отягощённый освобождением памяти при скроллировании, типа unidirectional, но с хранением не одной записи, а буфера заданного размера, я точно не знаю, но одно из двух по физике процесса.
paratruper писал(а): Изначально у меня была мысль что у фибов предусмотрена какая нибудь возможность быстрого перехода и установки курсора на необходимую запись, но что-то не могу найти.
Какая-нибудь. Угумс. А подумать слегка головом? :) Как бы ты лично такую возможность реализовал? Тама под низОм у на що? Прально, SQL-сервер. А в SQL что-либо похожее на слово Locate видал когда-нить? Серж, конечно, яркий представитель нашего клана магов и кудесников, но не всемогущ :)
paratruper писал(а): p.s. ВСЕ ЗАПИСИ НА КЛИЕНТА НЕ СЛИВАЮ... :):):) и сливать не буду :)
Да. И вправду не все. Только те, которые сзаду позиции, которую локатишь.

Добавлено: 14 июл 2006, 18:13
paratruper
Все :) про locate забыл. И даже на него как бы забИл. Решил вопрос следующим образом: вместо того что бы передавать в locate номер искомой записи буду делать аналог фибовского ограниченного кеша, то есть селектить нужную запись плюс несколько верхних и нижних для забивки грида(ну не обрадуеться пользователь если грид вдруг практически опустеет). Соответственно список отсортирован по order by. Единственное конечно было бы хорошо если бы в Фибах был предусмотрен какой нибудь параметр типа № поля или записи относительно которой работает ограниченый кеш, я бы просто отдал мой номер как параметр, датасет слил бы записи включая мою и сразу курсор бы туда поставил. Но что-то пока никак не могу найти в исходниках где он есть. Поэтому наверное придеться писать свою процедурку.
paratruper писал(а): Изначально у меня была мысль что у фибов предусмотрена какая нибудь возможность быстрого перехода и установки курсора на необходимую запись, но что-то не могу найти.
"Merlin" писал(а): Какая-нибудь. Угумс. А подумать слегка головом? :) Как бы ты лично такую возможность реализовал? Тама под низОм у на що? Прально, SQL-сервер. А в SQL что-либо похожее на слово Locate видал когда-нить? Серж, конечно, яркий представитель нашего клана магов и кудесников, но не всемогущ :)
вот если бы можно было добавить номер/id/значение записи относительно которой работает режим ограниченного кеша тогда вообще было бы великолепно. :) Знать бы как с Сергеем связаться, попросил бы такую вещь, так ведь сайт devrace не работает.:(
paratruper писал(а): p.s. ВСЕ ЗАПИСИ НА КЛИЕНТА НЕ СЛИВАЮ... :):):) и сливать не буду :)
"Merlin" писал(а): Да. И вправду не все. Только те, которые сзаду позиции, которую локатишь.
p.s. Про locate забыли :)

Добавлено: 14 июл 2006, 18:51
Merlin
paratruper писал(а):Все :) про locate забыл. И даже на него как бы забИл.
Ну и напрасно. Очень удобная и пользительная штука когда к месту. Например, инкрементальный поиск в ограниченной выборке. Или позиционирование всё той же ограниченной выборки после открытия на предустановленный ID.
paratruper писал(а): то есть селектить нужную запись плюс несколько верхних и нижних для забивки грида(ну не обрадуеться пользователь если грид вдруг практически опустеет). Соответственно список отсортирован по order by. Единственное конечно было бы хорошо если бы в Фибах был предусмотрен какой нибудь параметр типа № поля или записи относительно которой работает ограниченый кеш,
От же ж упёртый. И Фибы опять же тут ни при чом. И не поможет тебе Серж. Нету в реляционных базах никаких номеров записей. Не-ту. Есть ордер бай. Номер записи есть на клиенте, в уже отфетченном сформированном курсоре (RecNo). И при повторении запроса этот номер может быть у совсем другой записи. Для того, чтоб подать тебе произвольный фрагмент курсора именно по порядковому номеру, его где-то надо построить целиком и выкусить из него интересующий тебя кусок. Или действительно процедурой, с тремя запросами - "центральной" записи и двумя с разным направлением сортировки от заданного ID. Тока проктология это. В случае натуральной сортировки заставишь сервер для извлечения сотни дважды перебрать все 400000 записей. А потом ещё отсортировать полученный результат. Ты не о том думаешь. Надо думать об ограничении выборки используя её естественную природу и способ применения. Заставить пользователя использовать удобные и очевидные фильтры в Where. Например, чего-то там за заданный период времени. Или красного цвету. Или длиной от метра до полутора. Или всё вместе. Я ж не знаю что ты там фетчишь бочками. А в ограниченной до единиц тысяч выборке и полокейтиться не грех. Если записи не по тыще длинных чаровских полей в ширину.

Добавлено: 14 июл 2006, 18:54
WildSery
Немного оффтопа.
Обсуждение напоминает мне фразу одного моего программиста, который, подхватив в локальную сеть какой-то свежий вирус, спрашивает меня "А чем бы мне его вылечить, но только чтобы не Касперским, и не Dr.Web?"
Любим мы усложнять изначально простую задачу...

Добавлено: 14 июл 2006, 19:06
Merlin
Нет, просто инерция мысли после навигационных баз. Никак не переключиться на мышление операциями на множествах, всё тянет все вопросы решать переборами, циклами и позаписными чтениями. Я это в 94-м году проходил, переползаючи с Btrieve. Действительно очень тяжко было мозги переформатировать, да ещё транзакции эти :-D Зато как переформатировал, так хорошо стало :)

Добавлено: 14 июл 2006, 19:14
paratruper
Ну вот "запинали" меня по самое нехочу :)
Теперь по топику :)
Есть уникальный номер записи, онже ключ, он же id кому как удобно :)
Можно ведь привязаться к нему и сделать 3я запросами, на счет проктологии согласен, но если другого выхода нету.Или есть? :) Ограничением выборки в моём случае служит количество строк в гриде. Все. Больше записей пользователю видеть не надо. Но если поиск/ позиционрование записи нужно производить во ВСЕЙ таблице, тут как быть? Либо locate что очень долго и ресурсоемко, либо запросом что достаточно быстро, но несколько неудобно тем что вдобавок к выбраной записи придеться тянуть несколько рядомстоящих отсортированных по тому же самому id к примеру, чтобы заполнить ими грид. Потому что пользователь очень удивиться если вдруг останеться один клиент на гриде.
Понимаю что достал :) однако все равно спасибо всем кто помог разобраться. Написал Сергею в поддержку может быть он всетаки сделает то что я хочу, если это вообще можно сделать. А если нет буду колдовать с 3 селектами.

Добавлено: 14 июл 2006, 19:39
Merlin
Посмотрел ыщо раз нитку по диагонали. НУ Ё-МАЁ! (С) Прапор Шматко. Нафих те вообще полный список упал? Скока у тебя должников-то? Элементарный иннер джойн двух таблиц, чтоб дотянуться до атрибутов полного списка и фсё. А если поллимона именно должников, то это значит, что с ними работает не один человек. И эти человеки их делют. По каким-то признакам. Алфавитному, территориальному, диапазонным - размера долга, времени должания... А если таки один Сизиф катает таку каменюку, то тоже - сегодня работаю с такой вот категорией должников... И эти признаки и включаются в фильтр по результатам задушевной беседы с заказчиком. Или даже с конкретным исполнителем у заказчика.

Добавлено: 14 июл 2006, 20:15
paratruper
Ну вот %) начали за здравие а закончили... :)
Значит все дело в следующем:
Есть таблица ~400000 записей (клиенты) есть грид1 к нему подключен датасет1
и он же работает с таблицей то есть является визуальным её представлением :) (показывет клиентов которые есть в таблице) попрошу заметить не ВСЕ ЗАПИСИ ОДНОВРЕМЕННО, а ограниченое их количество (фетчиться примерно 100 записей)
есть датасет2 к нему подключен грид2 в датасете2 выводятся должники, которые являються теми же клиентами но с признаком "должны".(данные беруться из той же болшой таблицы плюс заджойниваються с ещё одной) тоже соответствено не все одновременно.
Теперь внимание. :) необходимо сделать так чтобы при клике на записи в гриде 2, в гриде 1 курсор автоматически ставился на запись соответствующего клиента.
Я делал это locate но как оказалось медленно, теперь буду делать вариант с 3 selecta'ми. Что бы выбрать в Грид 1 записи с искомой . Что я делаю неправильно? :)

Добавлено: 14 июл 2006, 20:47
Merlin
paratruper писал(а): Значит все дело в следующем:
Есть таблица ~400000 записей (клиенты) есть грид1 к нему подключен датасет1
и он же работает с таблицей то есть является визуальным её представлением :) (показывет клиентов которые есть в таблице)
Зачем? Для красоты?
paratruper писал(а): попрошу заметить не ВСЕ ЗАПИСИ ОДНОВРЕМЕННО, а ограниченое их количество
Ясен перец. В грид поллимона не войдёт, экран треснет.
paratruper писал(а): (фетчиться примерно 100 записей)
Начинается каскадная проктология. Бессмыссленный открытый запрос к полному списку, висячему как картинка, порождает проблемы с памятью на клиенте и нагрузкой на сеть. Это был первый каскад. Выбрасывать жалко, уже есть, знач наворачиваем следующий каскад - насилие над концепцией датасета, громко называемое режимом ограниченного кеша. Кстати, я лично не перебрался с IBX на плюсы именно из-за засилия в них рюшечек, отнюдь не способствующих пониманию разработчиком ни как работает сервер, ни как организована связь клиент-сервер, ни сути того, чем он вообще занимается, а позволяющих делать что и как привык на уровне языческого мировоззрения. Для строительства веб-междумордий (interfaces) в самом сервере есть first-skip (к кторому тоже надо подходить с пониманием и оглядкой), нафиг ещё это кастрирование подготовленного на сервере курсора, да ещё и обычно уже целого после сортировки, в tmp-файле? Стремление свести все функции системы к одной экранной форме? Мышление экранными контролами, а не сущностями, связями и функциями? Мрак. И Серж это поощряет :(
paratruper писал(а): есть датасет2 к нему подключен грид2 в датасете2 выводятся должники, которые являються теми же клиентами но с признаком "должны".(данные беруться из той же болшой таблицы плюс заджойниваються с ещё одной) тоже соответствено не все одновременно.
Ну и чудненько. Хорошая заготовка для выполнения определённой группы функций информационной системы.
paratruper писал(а): Теперь внимание. :) необходимо сделать так чтобы при клике на записи в гриде 2, в гриде 1 курсор автоматически ставился на запись соответствующего клиента.
Вот именно. Внимание: а для на зачем? Патамушта есть? Третий каскад?
paratruper писал(а): Я делал это locate но как оказалось медленно, теперь буду делать вариант с 3 selecta'ми. Что бы выбрать в Грид 1 записи с искомой .
Чем бы дитё не тешилось, лишь бы не вешалось.
paratruper писал(а): Что я делаю неправильно? :)
Думаешь. Руками, а не головой. Не хочу обидеть, хочу направить. Основа проектирования - функционально-целевой анализ и структурирование предметной области как совокупности модели и решаемых на ней задач. А не набрасывание на формы гридов и придумывание а что бы теперь с ними сделать.