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

Вниз

Ускорение выполнения SQL - запросов   Найти похожие ветки 

 
saNat ©   (2004-07-30 00:31) [40]

На рабочей форме лежит компонент PageControl. Его вкладки разбиты по темам. Например, информация о филиале, аварийные заявки, опасные заявки...
Ну вот не лежит у меня душа со времен университета к компонентам DB* (Grid и подобные)... Мне показалось что будет лучше написать свой модуль для чтения/записи БД, работающий со "стандартными" компонентами
Получилось нечто следующее:

//Чтение данных
Procedure TBDModule.ReadBD(Component:TObject; FieldsList:String;TablesList:String;WheresList:String;WhereOn:Boolean);
Var
 RowPosition:Integer;
 ColPosition:Integer;
Begin
//Определение количества полей запроса
FieldsCount:=SetFieldsCount(FieldsList);
With MySQL Do
 Begin
  //Деактивация компонента
  Close;
  //Очистка текста запроса
  SQL.Clear;
  //Добавление текста запроса
  SQL.Add("Select "+FieldsList+" From "+TablesList);
  If WhereOn
   Then SQL.Add("Where "+WheresList);
  //Выполнение запроса
  Open;
  //Установка указателя на первую запись
  First;
  //Вывод данных в компонент типа "TListBox"
  If Component.ClassName="TListBox"
   Then
    Begin
     //Очистить
     (Component As TListBox).Items.Clear;
     //Пока не закончатся данные
     While Not EOF Do
      Begin
       //Вывести значение
       (Component As TListBox).Items.Add(FieldByName(SetFieldsByNumber(FieldsList,1)).AsString);
       //Перейти к следующей записи
       Next;
      End;
    End;
  //Вывод данных в компонент типа "TCheckListBox"
  If Component.ClassName="TCheckListBox"
   Then
    Begin
     //Очистить
     (Component As TCheckListBox).Items.Clear;
     //Пока не закончатся данные
     While Not EOF Do
      Begin
       //Вывести значение
       (Component As TCheckListBox).Items.Add(FieldByName(SetFieldsByNumber(FieldsList,1)).AsString);
       //Перейти к следующей записи
       Next;
      End;
    End;
  //Вывод данных в компонент типа "TEdit"
  If Component.ClassName="TEdit"
   Then
    Begin
     //Очистить
     (Component As TEdit).Text:="";
     //Вывести значение
     (Component As TEdit).Text:=FieldByName(SetFieldsByNumber(FieldsList,1)).AsString;
    End;
  //Вывод данных в компонент типа "TLabel"
  If Component.ClassName="TLabel"
   Then
    Begin
     //Очистить
     (Component As TLabel).Caption:="";
     //Пока не закончатся данные
     While Not EOF Do
      Begin
       //Вывести значение
       (Component As TLabel).Caption:=(Component As TLabel).Caption+FieldByName(SetFieldsByNumber(FieldsList,1)).AsString+", ";
       //Перейти к следующей записи
       Next;
      End;
     (Component As TLabel).Caption:=Copy((Component As TLabel).Caption,1,Length((Component As TLabel).Caption)-2);
    End;
  //Вывод данных в компонент типа "TIDField"
  If Component.ClassName="TIDField"
   Then
    Begin
     //Очистить
     (Component As TIDField).Code:="";
     //Вывести значение
     (Component As TIDField).Code:=FieldByName(SetFieldsByNumber(FieldsList,1)).AsString;
    End;
  //Вывод данных в компонент типа "TStringGrid"
  If Component.ClassName="TStringGrid"
   Then
    Begin
     (Component As TStringGrid).RowCount:=2;
     ColPosition:=0;
     While ColPosition<=((Component As TStringGrid).ColCount-1) Do
      Begin
       (Component As TStringGrid).Cells[ColPosition,1]:="";
       Inc(ColPosition);
      End;
     RowPosition:=1;
     While Not EOF Do
      Begin
       ColPosition:=0;
       While ColPosition<=((Component As TStringGrid).ColCount-1) Do
        Begin
         (Component As TStringGrid).Cells[ColPosition,RowPosition]:=FieldByName(SetFieldsByNumber(FieldsList,ColPosition+1)).AsString;
         Inc(ColPosition);
        End;
       Next;
       If Not EOF
        Then
         Begin
          (Component As TStringGrid).RowCount:=(Component As TStringGrid).RowCount+1;
          Inc(RowPosition);
         End;
      End;
    End;
  If Component.ClassName="TComboBox"
   Then
    Begin
     (Component As TComboBox).Items.Clear;
     While Not EOF Do
      Begin
       (Component As TComboBox).Items.Add(FieldByName(SetFieldsByNumber(FieldsList,1)).AsString);
       Next;
      End;
    End;
 End;
End;

Внутрь я передаю объект, в который собираюсь выводить данные, список полей, список таблиц и список условий отбора (если требуется - последний параметр). Т.К. с TStrings я до конца не разобрался (пока), то параметры передаются строкой и пришлось сделать метод для поиска метода по его порядку в списке... После самого запроса следует реализация вывода в различные "объекты-приемники."


 
saNat ©   (2004-07-30 00:45) [41]

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

TIDField=Class(TObject)
 Code:String;
End;

Здесь пришлось следовать идее - в метод передаем объект. Писать отдельный метод для получения идентификатора не хотелось (хотя...)
Дальше посылаем запрос на вывод данных о филиале в Label"ы.
Вышеописанное выглядит так:

//Вывести окно
PhilialSelect.ShowModal;
//Если выбран филиал...
If PhilialSelect.PhilialName<>"None"
 Then   //...то
  Begin
   //Вывести значение в соответствующее окно
   PhilialName.Text:=PhilialSelect.PhilialName;
   //Вывести адрес филиала
   BDModule.ReadBD(AddressValue,
                   "Address",
                   "PhilialTable",
                   "ID=""+ThisID+""",True);
   //Если значений нет...
   If AddressValue.Caption=""
    Then   //...вывести подпись
     AddressValue.Caption:="отсутствует";
   //Вывести кода телефон АДС
   BDModule.ReadBD(ADSPhoneValue,
                   "PhoneCode",
                   "PhilialTable",
                   "ID=""+ThisID+""",True);
   //Если значений нет...
   If ADSPhoneValue.Caption=""
    Then   //...вывести подпись
     ADSPhoneValue.Caption:="отсутствует";
   //Запись кода во вспомогательную переменную
   BufString:="("+ADSPhoneValue.Caption+") ";
   //Вывести телефоны АДС
   BDModule.ReadBD(ADSPhoneValue,
                   "Number",
                   "PhoneTable,PhilialPhoneTable",
                   "(PhilialPhoneTable.PhilialID=""+ThisID+"")And"+
                   "(PhilialPhoneTable.PhoneID=PhoneTable.ID)And"+
                   "(PhoneTable.Type="1")",True);
   //Если значений нет...
   If ADSPhoneValue.Caption=""
    Then   //...вывести подпись
     ADSPhoneValue.Caption:="отсутствует";
   ADSPhoneValue.Caption:=BufString+ADSPhoneValue.Caption;
   //Вывести сотовый АДС
   BDModule.ReadBD(ADSMobileValue,
                   "Number",
                   "PhoneTable,PhilialPhoneTable",
                   "(PhilialPhoneTable.PhilialID=""+ThisID+"")And"+
                   "(PhilialPhoneTable.PhoneID=PhoneTable.ID)And"+
                   "(PhoneTable.Type="4")",True);
   //Если значений нет...
   If ADSMobileValue.Caption=""
    Then   //...вывести подпись
     ADSMobileValue.Caption:="отсутствует";
   //Вывести факс
   BDModule.ReadBD(FaxValue,
                   "Number",
                   "PhoneTable,PhilialPhoneTable",
                   "(PhilialPhoneTable.PhilialID=""+ThisID+"")And"+
                   "(PhilialPhoneTable.PhoneID=PhoneTable.ID)And"+
                   "(PhoneTable.Type="3")",True);
   //Если значений нет...
   If FaxValue.Caption=""
    Then   //...вывести подпись
     FaxValue.Caption:="отсутствует";
   //Вывести адрес электронной почты
   BDModule.ReadBD(ADSEMailValue,
                   "EMail",
                   "PhilialTable",
                   "ID=""+ThisID+""",True);
   //Если значений нет...
   If ADSEMailValue.Caption=""
    Then   //...вывести подпись
     ADSEMailValue.Caption:="отсутствует";
//Обновление списка поступивших заявок
   RefreshWarningPage;
   RefreshOutPage;
   RefreshClearPage;
  End;
End;


//Нужно удалить принудительный вывод "отсутствует" - в БД автоматом ставится значение по умолчанию - сам знаю :-)
Предположим поступает заявка. В новом окне выводится список персонала, список авто и список номеров авто (по этому поводу пока сам думаю - есть идея отделить типы автомобилей от их номеров - для уменьшения избыточности, с другой стороны во всем надо знать меру - тогда можно одним списком выводить и машиу и номер. пока думаю). Так же выводится список стандартных работ по данной заявке. Получаем такой фрагмент:

BDModule.ReadBD(NewWarning.ADSPeopleList,
                "FIO",
                "PeopleTable,PhilialPeopleTable",
                "(PhilialID=""+ThisID+"")And"+
                "(PeopleID=ID)",True);
BDModule.ReadBD(NewWarning.ADSAutoTypeList,
                "AutoType",
                "AutoTable",
                "PhilialID=""+ThisID+""",True);
BDModule.ReadBD(NewWarning.ADSAutoNumberList,
                "AutoNumber",
                "AutoTable",
                "PhilialID=""+ThisID+""",True);


Эти списки приходится заполнять перед или во время активации формы, т.к. они разные для каждого филиала.


 
saNat ©   (2004-07-30 00:49) [42]

При отладке возникает самая большая пауза во время выполнения SQL.Open. При выполнении нескольких запросов эта задержка ощутима. Особенно, если учесть, что под диктовку нужно вводить несколько заявок. Вроде бы количество запросов не большое (максимум 5) и количество выбираемых данных мало - до 1000 записей на будущее.

По-моему по сути вопроса это все. Хотя может и упустил чего. Желающим могу скинуть исходники... Спасибо всем откликнувшимся.

С уважением...


 
sniknik ©   (2004-07-30 08:42) [43]

упустил, компаненты доступа, используемый драйвер(движок), связь между компанентами (или отсутствие таковой)...

насчет показаного, как и думал... хреново. стандартные db компаненты более интелектуальны...
передаются все строки независимо от того нужны ли они для отображения, преобразование в строку, используется поиск имени (fieldbyname) в цикле, и для заполнения разных компанент используется переоткрытие и сканирование одной и той же таблицы только потому что поля заполнения разные.
все это очень нехорощо.

теперь к SQL.Open, говориш задержка? а сколько? секунда, две, минута?
если компаненты работают/настроены по серверной технологии то перекачка данных обязательно займет какоето время... вопрос, оправданое ли, или действительно тормозят, а этого у тебя не понятно.
вот я делаю запрос простой к таблице в ней 25 полей все числовые, записей 2076. отрабатывает (open) за 0,1сек. это как для тебя задержка?


 
Sergey13 ©   (2004-07-30 09:27) [44]

2saNat ©   (30.07.04 00:16)
>Поэтому на первом этапе предполагается ввод данных по телефону, но не в стандартные бумажные формы, а посредством приложения-сервера.
Не делай этого!!! Тебя проклянут и загубят этим может быть неплохую идею.

>Ну вот не лежит у меня душа со времен университета к компонентам DB* (Grid и подобные)... Мне показалось что будет лучше написать свой модуль для чтения/записи БД, работающий со "стандартными" компонентами
Прикинь - приходит парень, ездивший до этого на велосипеде как любитель, в авторем мастерскую и говорит - "ну не лежит у меня душа к карбюратору, мне кажется...".


 
Rule ©   (2004-07-30 09:42) [45]

//Прикинь - приходит парень, ездивший до этого на
//велосипеде как любитель, в авторем мастерскую и говорит -
//"ну не лежит у меня душа к карбюратору, мне кажется...".

Вот это мне понравилось, в предыдущем посте, вот атк оно и есть,  не придумывай велосипед, ради бога, если тыхочешь использовать парадокс и стандартные компоненты, то возьми ты этот BDE  да и напиши программку, только напиши правильно, разберись как это сделать, иначе тебе же потом хуже будет, прийдется все переписывать а перед этим ещё помучатся нехило,
вот тебе ссылки от АП

http://podgoretsky.com/cgi-bin/dlcounter/npscnt?file=http://podgoretsky.com/ftp/Docs/Delphi/Kuzmenko/bde.htm&file_id=Kuz menkoBDE

http://podgoretsky.com/cgi-bin/dlcounter/npscnt?file=http://podgoretsky.com/ftp/Docs/Delphi/D7/d7stb/index.html&file_id= d7stb

я думаю достаточно пока, если чего покапаешься у подгоретского или в гугле, там достаточно всего


 
Term   (2004-07-30 09:59) [46]

мдя задача тривиальная, а наворотил то ... и главный вопрос ЗАЧЕМ???
я этими компонентами DBGrid пользуюсь всю жизнь и не разу никаких проблем не было.
Зачем тратить время на то что и так сделано давно и намного лучше, или ты думаеш в Боорланде народ глупее тебя сидит :)))
В общем брось эту дурь со стринггридом, его надо использовать там где надо, а не в извращениях.
И самое что меня заинтересовало чем тебе DBGrid не угодил, уж просвети чтобы все знали, а то ничего конкретного ты не сказал


 
Rule ©   (2004-07-30 10:29) [47]

Да кстати по поводу гридов, советую разобраться в EhLib"e, вот если разберешся я тебе гарантирую что 90 процентов тебе больше ничего не захочется а если захочется, то просто допишешь до этой библиотеки чего захочется и вернешь разработчикам что и другие воспользовались тем что тебе захотелось, вот так


 
Term   (2004-07-30 11:52) [48]


> советую разобраться в EhLib"e,

это точно, там есть много такого что тебя обрадует :)))


 
dtm   (2004-07-30 15:12) [49]

[40] - [41]
Божачка ;)... I робяць жа людзi дарэмныя рэчы ... =)

[47] Rule
А если захочется, то пусть посмотрит DevExpress Quantum Grid Suite. После этого точно не захочется ;)


 
Slym ©   (2004-07-30 16:39) [50]

Парень.. ты про BeginUpdate/EndUpdate слышал?...
и о DisableControls/EnableControls...

И еще часто ганяясь за одним критерием приходится жертвовать другим...


 
Term   (2004-07-30 17:09) [51]


> Парень.. ты про BeginUpdate/EndUpdate слышал?...
> и о DisableControls/EnableControls...


это ты автору??? то явно не к месту :)))



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

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

Наверх





Память: 0.59 MB
Время: 0.042 c
3-1091388558
Начинающий
2004-08-01 23:29
2004.08.22


3-1091433008
Last
2004-08-02 11:50
2004.08.22
Проверка вводимого значения в DBGrid


9-1083477699
Smoke_Gomel
2004-05-02 10:01
2004.08.22
Анимированные спрайты в Delphix


3-1091168902
som
2004-07-30 10:28
2004.08.22
Про SQL запросы


3-1091096115
otistarda
2004-07-29 14:15
2004.08.22
Создание ADOConnection





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский