Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Запрос на выборку   Найти похожие ветки 

 
Fedor   (2009-05-21 16:48) [0]

Как при помощи sql запроса отображать только то количество записей, которое убирается в область отображения DBGrid? Например пусть DBGrid может отображать 10 записей.


 
Sergey13 ©   (2009-05-21 16:58) [1]

Иди от обратного - запрашивай ТОЛЬКО те данные, которые нужны пользователю СЕЙЧАС.


 
Ega23 ©   (2009-05-21 17:05) [2]


> Как при помощи sql запроса отображать только то количество
> записей, которое убирается в область отображения DBGrid?
>  Например пусть DBGrid может отображать 10 записей.


Тут такая штука. У тебя на экране DBGrid отображает 10 записей. Потом ты окошко на весь экран развернул - и он начал отображать уже 40 записей. Потом поменял разрешение экрана - и уже 28 записей.
На каждый такой раз "стрелять" в базу запросом... Ну не знаю. ИМХО, непродуктивно.

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


 
Fedor   (2009-05-21 17:12) [3]

А пользователю и нужны те записи что отображены в гриде. Кроме того он еще и скролирует его. На вскидку, я думаю так: мы отображаем первые 10 записей.
select top 10 * from table order by id.
Затем пользователь начинает "бегать" по гриду изменяя позицию.
Когда он попадает на последнюю запись в гриде мы выполняем запрос типа:
select top 10 * from table where id>=:id order by id.
Пользователь в гриде получит следующие 10 записей с текущей.
Так же можно сделать и при переходе на первую запись в гриде:
select top 10 * from table where id<=:id order by id.
Где параметр :id - id текущей записи.

Возможно так.


 
Fedor   (2009-05-21 17:18) [4]


> Тут такая штука. У тебя на экране DBGrid отображает 10 записей.
>  Потом ты окошко на весь экран развернул - и он начал отображать
> уже 40 записей. Потом поменял разрешение экрана - и уже
> 28 записей.На каждый такой раз "стрелять" в базу запросом.
> .. Ну не знаю. ИМХО, непродуктивно.Ты лучше задачу в целом
> опиши. Какие есть исходные данные, и что бы ты конкретно
> хотел бы получить. Тут народ опытный, может чего интересного
> посоветуют.


Пусть размер грида жесткий на 10 записей. В базе порядка 500 основных записей с фотками, плюс к каждой из в присоединенной таблице по несколько сотен записей. Сейчас вес базы около 40 мегов. А отображать нужно сразу все включая графику Chart по детальным таблицам.
Просто думаю если отображать главную таблицу частями быстрее будет.


 
Виталий Панасенко   (2009-05-21 17:21) [5]


> Просто думаю если отображать главную таблицу частями быстрее
> будет.

А овчинка вычинки стоит?


 
Ega23 ©   (2009-05-21 17:29) [6]


> Просто думаю если отображать главную таблицу частями быстрее
> будет.


Нет. Ты отображай детали только по текущей записи. Т.е. когда ты в гриде перешёл на новую запись - отрабатывает маленький подзапрос, который вытаскивает только то, что принадлежит ей.
Короче, как пример.

Create MasterTable (MID int, MName varchar(32))
Insert into MasterTable (MID, MName) Values (1, "M1");
....
Insert into MasterTable (MID, MName) Values (10, "M10");

Create DetailTable (DID, MID (ключ на Master), Name)
Insert into DetailTable (DID, MID, Name) Values (1, 1, "D11");
Insert into DetailTable (DID, MID, Name) Values (2, 1, "D12");
....
Insert into DetailTable (DID, MID, Name) Values (10, 1, "D110");
Insert into DetailTable (DID, MID, Name) Values (11, 2, "D21");
....
Insert into DetailTable (DID, MID, Name) Values (100, 10, "D1010");

Итого: в мастере - 10 записей, для каждой записи в мастере - 10 записей в детали.

Кладём 2 грида, 2 DataSet, 2 DataSource и настраиваем Master-Detail связку (об этом в книге почитай).
Получается, что в один момент времени загружено всего 20 записей: 10 в мастере, и 10 в детали, которая соответствует текущему значению Мастера.

Как-то так.


 
Медвежонок Пятачок ©   (2009-05-21 17:31) [7]

Возможно так.

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


 
Fedor   (2009-05-21 17:31) [8]

Эксперемент. Будет прирост скорости - очень хорошо. Есть конечно подозрение, что лишние запросы при навигации съедят все увеличение скорости работы.


 
Медвежонок Пятачок ©   (2009-05-21 17:32) [9]

если вообще будет что съедать


 
sniknik ©   (2009-05-21 17:55) [10]

> Просто думаю если отображать главную таблицу частями быстрее будет.
будет медленнее.

> В запрос может попасть тысяча записей.
> Если он привязан к гриду, то фетч идет до тех пор, пока не кончится место в его клиентской части.
1000 записей выбирается за 0,01 секунды максимум. одна отрисовка формы с гридом гораздо существеннее по времени.
и фетч при локальном курсоре отбирает все.

> Есть конечно подозрение, что лишние запросы при навигации съедят все увеличение скорости работы.
есть подозрения, что твои "тормоза" не имеют ничего общего с теми, что ты ищешь...


 
Ega23 ©   (2009-05-21 17:55) [11]


> Если он привязан к гриду, то фетч идет до тех пор, пока
> не кончится место в его клиентской части.


Я бы не стал заходить так далеко и выражаться столь категорично. Всё от конкретной реализации TDataSet зависит.


 
Fedor   (2009-05-22 09:24) [12]


> есть подозрения, что твои "тормоза" не имеют ничего общего
> с теми, что ты ищешь...


Возможно. Опишу проблему.
Поиск организован следующим образом:

procedure TForm1.Edit2Change(Sender: TObject);
begin
 if Edit2.Text<>"" then
   begin
     CustDS.Close;
     CustDS.CommandText:="select * from customers where surname like ""+Edit2.Text+"%" order by card";
     CustDS.Open;
   end
   else
   begin
     CustDS.Close;
     CustDS.CommandText:="select * from customers order by card";
     CustDS.Open;
   end;
end;

Когда мы вводим текст в поле Edit все работает замечательно. Но стоит очистить поле база замирает выполняя запрос

select * from customers order by card

На слабых машина прога виснет. На моем ноуте Core2Duo с 4 гигами задержка примерно секунды 3. Количество записей около 500 записей с фотками. Может так быть должно?


 
Медвежонок Пятачок ©   (2009-05-22 09:27) [13]

ты посчитай сколько раз при этом вызывается onchange


 
MsGuns ©   (2009-05-22 09:29) [14]

>Fedor   (21.05.09 17:12) [3]
>А пользователю и нужны те записи что отображены в гриде. Кроме того он еще и скролирует его. >На вскидку, я думаю так: мы отображаем первые 10 записей.
>Затем пользователь начинает "бегать" по гриду изменяя позицию.
>Когда он попадает на последнюю запись в гриде мы выполняем запрос типа:

Эта.. вот собрались друзья отметить событие, сбегали в лавку, купили чекушку. Дернули - сбегали еще раз в лавку - купили по огурцу, закусили. Затем опять сбегали за новой чекушкой, дернули. Сбегали за 100 гр. колбаски - закусили.
И т.д.


 
Медвежонок Пятачок ©   (2009-05-22 09:36) [15]

>Когда он попадает на последнюю запись в гриде мы выполняем запрос типа:

Предварительно промедитировав куда именно в будущем направится юзер с этой записи. Вверх или вниз. Или вообще никуда не направится, а закроет программу через 10 секунд.


 
Fedor   (2009-05-22 09:40) [16]


> ты посчитай сколько раз при этом вызывается onchange


Два раза. Например мы ввели символ "а" - у нас список фамилий на "а". Нажали "Backspace" - у нас таблица полностью.


 
Сергей М. ©   (2009-05-22 09:44) [17]


> Fedor   (22.05.09 09:24) [12]


1. У тебя поле card индексировано ?
2. Курсор НД на клиентской или серверной стороне ?
3. Так ли уж необходим инкрементальный поиск/выборка ?


 
Fedor   (2009-05-22 09:51) [18]


> 1. У тебя поле card индексировано ?


Да. На уровне создания базы.
Вот в DataSet это не отмечено.


> 2. Курсор НД на клиентской или серверной стороне ?


Клиент.


> 3. Так ли уж необходим инкрементальный поиск/выборка ?


Очень нужен.


 
Ega23 ©   (2009-05-22 09:55) [19]


> Очень нужен.


А зачем на OnChange вешать? Положи рядом кнопочку "Обновить".
Да, и если уж на то пошло, то:
procedure TForm1.Edit2Change(Sender: TObject);
begin
 with CustDS do
 begin
   Close;
   if (Edit2.text = "") then
      CommandText := ....
   else
      CommandText := ....;

   try
     Open;
   except
      .....
   end;
 end;


 
Виталий Панасенко   (2009-05-22 09:58) [20]

А почему фотки не показывать отдельно? точнее, фетчить? бегай себе по гриду, нужно показать всю инфу(фото) - выборка ОДНОЙ ЗАПИСИ для показа


 
Сергей М. ©   (2009-05-22 10:27) [21]


> в DataSet это не отмечено


Что значит "не отмечено" ?


 
MsGuns ©   (2009-05-22 10:58) [22]

>На слабых машина прога виснет. На моем ноуте Core2Duo с 4 гигами задержка примерно >секунды 3. Количество записей около 500 записей с фотками.

Во как !
Решение в [20] - т.е. извлекаются все поля, которые можно внятно (т.е. текстом) показать в сетке. А для фоток кнопульку, по нажатию на которую с сервера тянется блоб (блобы) ТОЛЬКО ПО ТЕКУЩЕЙ ЗАПИСИ. Ну примерно так, как это показано в фильмах, где смотрят разные досье


 
Медвежонок Пятачок ©   (2009-05-22 11:18) [23]

Два раза. Например мы ввели символ "а" - у нас список фамилий на "а". Нажали "Backspace" - у нас таблица полностью.

Например он сначала ввел "ля-ля-тополя", а потом притопил backspace


 
sniknik ©   (2009-05-22 11:51) [24]

> Но стоит очистить поле база замирает выполняя запрос
на выборке без условий, т.е. 500 записей? смешно. где то еще есть неучтенные тормоза, может у тебя какие то события привязаны к датасету.
проверь свой полный запрос в независимой проге, например -
http://webfile.ru/3635677
тоже 3 сек?

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


 
Игорь Шевченко ©   (2009-05-22 11:58) [25]


> 1000 записей выбирается за 0,01 секунды максимум


Это смотря какой запрос


 
sniknik ©   (2009-05-22 12:04) [26]

> Это смотря какой запрос
в accecc особо сложных не бывает.

тем более здесь уже явно указан
> CustDS.CommandText:="select * from customers order by card";
выполняется 3 сек на Core2Duo с 4 гигами.

очевидно что то не так.


 
Нат   (2009-05-23 00:56) [27]

1. Зачем в гриде поле с фоткой?
Все равно толком не отобразить.
Для фотки сделать отдельный запрос и датасет.
2. ADODataSet сам (внутри себя) реализует то, что Вы пытаетесь сделать.
Для этого есть свойства CacheSize, BlockReadSize  и MaxRecords и событие OnEndOfRecordSet


 
sniknik ©   (2009-05-23 13:09) [28]

> Для фотки сделать отдельный запрос и датасет.
зачем? блоб поля и так не включаются в датасет, и скачиваются с сервера только при обращении т.е. тут при отрисовке.

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


 
Нат ©   (2009-05-24 04:06) [29]

Да, проблема не локализована.
По поводу ускорения.
1. Преступно формировать запрос "select ..." + Edit2.Text
Можно гарантировать, что в едите не всегда будут правильные данные.
2. Вы похоже обрабатываете запрос на ввод каждого символа.
Может быть стоит ужесточить условия отбора вводом как минимум 2..3-х символов. Кроме того, стоит проверять на пустоту едита.
Т.о. сначала присваиваете в переменную, если имеется пустое значение, подставляйте что-нибудь, что не позволит вывести все записи.
3. В большинстве случаев можно явно указать требуемые поля.
Выводите не все, а минимум, необходимый в гриде.
Для подробных сведений, делайте Детайл - все поля будете выводить только для одной записи.
Например.
If lenght(Edit2.Text) <3 then TextVal := "Ключ к записи, которая выводится по умолчанию"
else  TextVal := Edit2.Text;
"select id, tel, adr, director ..." + TextVal + "%";
Таким образом, вы будете перекачивать по сети на порядок меньше информации.


 
Нат ©   (2009-05-24 04:14) [30]

Поправлю
If lenght(Edit2.Text) <3 then TextVal := "Ключ к записи, которая выводится по умолчанию"
else  TextVal := Edit2.Text + "%";
"select id, tel, adr, director ..." + TextVal ;
Добавлять впереди "%" - нет смысла, это ограничит возможности.
Без первого "%" поиск осуществляется с начала строки.
Если пользователь желает, он сам добавит "%" в эдит, и поиск пойдет по вхождению подстроки с любого места.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.058 c
2-1271443216
fiascko
2010-04-16 22:40
2010.08.27
invalid floating point operation


2-1268800942
zergost
2010-03-17 07:42
2010.08.27
как запихать в DBGrid данные


15-1270197774
12
2010-04-02 12:42
2010.08.27
Тоже про природу. Объясните феномен.


2-1271766736
Ванич
2010-04-20 16:32
2010.08.27
TMemo


2-1273619311
NasdaqPredictor
2010-05-12 03:08
2010.08.27
О написании собственной 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
Английский Французский Немецкий Итальянский Португальский Русский Испанский