Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Производительность [IB6.x]


Страницы:   1 2

xayam ©   (2007-10-08 16:06:00) 

Решил тут недавно написать небольшой поисковичек для делфимастера по старым веткам незнаю че то интересно стало, написал загрузчик из xml'я в бд благо с 2004 года ветки в xml'е сохраняют)) Но возникли некоторые проблемы с производительностью, ищет медленно.
вот основной запрос на поиск
http://xayam.by.ru/Images/db2.gif

Хотя я думаю дело не в запросе. А в параметрах бд: кеш, sweep interval, размер страницы, индексы. Так вот какую совокупность этих параметров можно считать оптимальной? Есть ли какие-то другие способы увеличения производительности? Что посоветуете


xayam   (2007-10-20 17:26:00) [1]


> Desdechado ©

вот код который тормозит. Как Вы считаете можно где-нибудь оптимизировать его? Код рабочий, но тормозит страшно.

procedure TFdms.FileXMLFound(Sender: TObject;
                         const FileName, Folder: String; SR: TSearchRec);
var Root: IXMLNode;
    i, CurrID, MsgID, WordID: Integer;
    s, s1, s2, s3, sTitle      : String;
    Dest: TStrings;
begin s:= '';
     AddCom(' Загрузка файла ' + FileName);
 try
     XML.LoadFromFile(Folder + '\' + FileName);
     Root:= XML.DocumentElement;

     with pFIBDataSet1 , pFIBDataSet1.SelectSQL do
     try
          if not Transaction.Active then Transaction.StartTransaction;

          CurrID:= pFIBDatabase1.Gen_ID('GEN_TRD', 1);

          Clear;
          sTitle:= StringReplace(Root.Attributes['tit'], '''', '''''', [rfReplaceAll]);
          Add('insert into TRD (ID_TRD, DSC, DT, TITLE, FILENAME)');
          Add('values');
          Add('('+ IntToStr(CurrID) + ',''' + Root.Attributes['dsc'] + ''',''' +
                   Root.Attributes['dt'] + ''',''' +
                   sTitle +
                   ''',''' + FileName + '''' +
              ')');

          Active:= True;
          Transaction.Commit;

     except
          on E: Exception do
        with MOut.Lines   do begin
             Add('-------Except-------');
             Add(E.Message);
             Add(pFIBDataSet1.SelectSQL.Text);
             Transaction.Rollback;
             exit;
        end;
     end;

     with pFIBDataSet2, pFIBDataSet2.SelectSQL do
     for i:= 0 to Root.ChildNodes.Count - 1 do //цикл по всем сообщениям
     try
           MsgID:= pFIBDatabase1.Gen_ID('GEN_MESSAGES', 1);

           if not Transaction.Active then Transaction.StartTransaction;

           Clear;

           s1:= Root.ChildNodes[i].ChildNodes[0].XML;
           s1:= Copy(s1, 6, Length(s1) - 11); //логин  NodeValue

           s2:= Root.ChildNodes[i].ChildNodes[1].XML;
           s2:= StringReplace(Copy(s2, 6, Length(s2) - 11), '''', '''''',
                                          [rfReplaceAll]); //текст сообщения

           s:= s + s2;

           s3:= Root.ChildNodes[i].Attributes['dt'];

           Add('insert into MESSAGES (ID_MESSAGE, FK_MESSAGE, DT, LOGIN, MSG)');
           Add('values');
           Add('('+ IntToStr(MsgID) + ',' + IntToStr(CurrID) + ',''' + s3 + ''',''' +
                    StringReplace(s1, '''', '''''', [rfReplaceAll]) +
                    ''',''' +
                    s2 + '''' +
               ')');

           Active:= True;
           Transaction.Commit;

     except
          on E: Exception do
        with MOut.Lines   do begin
             Add('-------Except2-------');
             Add(E.Message);
             Add(pFIBDataSet2.SelectSQL.Text);
             Transaction.Rollback;
        end;
     end;

             s:= sTitle + ' ' + s;
             Dest:= TStringList.Create;
             StringToWords(s, Dest);

       with FIBQuery, FIBQuery.SQL do
        for i:= 0 to Dest.Count - 1 do
      begin
                  try
                      if not Transaction.Active then Transaction.StartTransaction;
                      WordID:= pFIBDatabase1.Gen_ID('GEN_WORDS', 1);
                      Clear;
                      Add('insert into WORDS (ID_WORD, WORD) values ');
                      Add('(' + IntToStr(WordID) + ',''' +
                            AnsiUpperCase(Dest[i]) + '''' +
                          ')'
                         );
                      ExecQuery;
                  except
                      on E: Exception do
                    with MOut.Lines   do begin
                         Add('-------Except15-------');
                         Add(E.Message);
                         Transaction.Rollback;
                         with pFIBDataSet2 , pFIBDataSet2.SelectSQL do
                         try
                             if not Transaction.Active then Transaction.StartTransaction;
                             Clear;
                             Add('select ID_WORD from WORDS where ');
                             Add('WORD = ''' + AnsiUpperCase(Dest[i]) + '''');
                             Active:= True;
                             WordID:= Integer(Fields[0].Value);
                             Transaction.Commit;
                         except
                             on E: Exception do
                           with MOut.Lines   do begin
                                Add('-------Except25-------');
                                Add(E.Message);
                                Transaction.Rollback;
                            end;
                         end;
                     end;
                  end;

                  try
                      if not Transaction.Active then Transaction.StartTransaction;
                      Clear;
                      Add('insert into TRDWRD (FK_WORD, FK_TRD) values ');
                      Add('(' + IntToStr(WordID) + ',' +
                                IntToStr(CurrID) +
                          ')'
                         );
                      ExecQuery;
                  except
                      on E: Exception do
                    with MOut.Lines   do begin
                         Add('-------Except20-------');
                         Add(E.Message);
                         Transaction.Rollback;
                    end;
                  end;
      end;

 except
          on E: Exception do
        with MOut.Lines   do begin
             Add('-------Bad-------');
             Add(E.Message);
             Add(FileName);
        end;
 end;
     DeleteFile(Folder + '\' + FileName);
end;


xayam   (2007-10-19 19:23:00) [2]


> Desdechado ©   (19.10.07 19:10) [31]
> > все равно тормозит индексирование
> Это же разовая операция.

ну да, только приходится делать дополнительный запрос select при индексировании слова, которое уже есть в таблице words, чтобы получить id этого слова. Из-за этого скорей всего.


Desdechado   (2007-10-19 19:10:00) [3]

> все равно тормозит индексирование
Это же разовая операция.

> расскажите про словоформы
Здесь я не силен, увы.


xayam   (2007-10-19 18:20:00) [4]

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


xayam   (2007-10-19 15:55:00) [5]

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

> Desdechado

расскажите про словоформы пожалуйста


xayam   (2007-10-19 14:31:00) [6]

еще один вопрос. У меня реально тормозит индексирование по словам, но это из-за того что я использую регулярные выражения. Есть ли какой-нибудь быстрый алгоритм разбиения текста на слова?


xayam   (2007-10-19 14:15:00) [7]


> Desdechado ©   (19.10.07 13:49) [25]
> В твоем запросе FROM Messages лишнее (неиспользуется), что
> дает декартово произведение, которое ты по наивности пытаешься
> "задавить" DISTINCT, который в свою очередь приводит к неявной
> сортировке.

огромное спасибо, серцем чуял что с DISTINCT что-то не то)) время поиска сократилось от бесконечности (по крайне мере я честно ждал два часа)) до 1 секунды

> И первичный ключ в TRDWRD лишний. Достаточно поставить уникальность
> на комбинацию двух внешних ключей.

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


Sergey13   (2007-10-19 14:05:00) [8]

> [23] xayam ©   (16.10.07 15:24)
> опять тормозит

При исследовании тормозов первое дело глянуть на план выполнения.


Desdechado   (2007-10-19 13:49:00) [9]

В твоем запросе FROM Messages лишнее (неиспользуется), что дает декартово произведение, которое ты по наивности пытаешься "задавить" DISTINCT, который в свою очередь приводит к неявной сортировке.

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

А вообще структура не очень удачная, имхо. Я бы слова прицеплял к постам, а не к веткам, хотя это дело вкуса.
И первичный ключ в TRDWRD лишний. Достаточно поставить уникальность на комбинацию двух внешних ключей.


xayam   (2007-10-19 13:28:00) [10]

up


xayam   (2007-10-16 15:24:00) [11]


> Desdechado ©

вот структура бд http://xayam.narod.ru/shema.gif
вот примерный запрос http://xayam.narod.ru/sql.gifопять тормозит. Что я делаю не так?


xayam   (2007-10-15 16:09:00) [12]


> Desdechado ©   (08.10.07 17:21) [15]
> > в смысле плохо что
> Можно и не целые, но тогда тоже LIKE, хотя для поиска начала
> слова индекс будет использоваться.
> А словоформы можешь прикрутить сам.
> С фразами будет сложнее.

ну вот переделал все нафиг)) перешел на FB 2.0.3, установил компоненты FBPlus, переделал структуру базы, проиндексировал все слова в названиях веток и сообщениях, работает поиск по одному слову. А как с словоформами делать? если можно подробнее пожалуйста))


Desdechado   (2007-10-11 16:42:00) [13]

А пользователю показывать оригинальный текст поста, сохраненный в блобе.
БД увеличится не на порядок, а в полтора раза, т.к. слова в постах повторяются, да и нет смысла индексировать слова короче 3-4 букв, их никто искать не будет.
И что поделать, за скорость нужно платить. Тут палка о двух концах, как всегда - размер/скорость.


xayam   (2007-10-11 15:53:00) [14]


> Desdechado ©   (11.10.07 15:22) [19]
>  Обязательно при каждом поиске апперить поле, чтоб узнать,
>  какое в нем будет значение?

а пользователю что тоже апер-поле показывать? или другое делать? так база увеличится на порядок


Desdechado   (2007-10-11 15:22:00) [15]

> жалко, тогда переделывать не вижу особого смысла.
Странная логика. А что, слово сразу UPPER сохранить нельзя? Обязательно при каждом поиске апперить поле, чтоб узнать, какое в нем будет значение?


xayam   (2007-10-11 14:06:00) [16]


> Sergey13 ©   (11.10.07 13:52) [17]

жалко, тогда переделывать не вижу особого смысла.


Sergey13   (2007-10-11 13:52:00) [17]

> [16] xayam ©   (11.10.07 13:49)

Тут важно, что перед этим.

Если
FieldName like UPPER('word')...
то будет

Если
Upper(FieldName) like UPPER('word')...
нет. В этом случае нужен индекс по Upper(FieldName), т.е. по функции, а этого в ИБ6, насколько я знаю, нет.


xayam   (2007-10-11 13:49:00) [18]

Еще один вопрос. А запрос вида
...like UPPER('word')... без % по индексу обрабатываться будет или нет?


Desdechado   (2007-10-08 17:21:00) [19]

> в смысле плохо что
Можно и не целые, но тогда тоже LIKE, хотя для поиска началаслова индекс будет использоваться.
А словоформы можешь прикрутить сам.
С фразами будет сложнее.


xayam   (2007-10-08 17:17:00) [20]


> Desdechado ©   (08.10.07 17:11) [13]
> > да это тоже плохо
> Уже успел попробовать?

нет конечно))
в смысле плохо что

> только целые слова
> и только в тех формах, какие есть в тексте


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо