Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.11;
Скачать: CL | DM;

Вниз

Производительность   Найти похожие ветки 

 
xayam ©   (2007-10-08 16:06) [0]

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

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


 
Sergey13 ©   (2007-10-08 16:10) [1]

> [0] xayam ©   (08.10.07 16:06)
> Хотя я думаю дело не в запросе.

Ошибаешься. Как раз в нем. При запросе с Like "%xxx%" не используется инедекс и идет полное сканирование таблицы.


 
xayam ©   (2007-10-08 16:12) [2]


> При запросе с Like "%xxx%"

хм... а как же по-другому, не очень хорошо знаю sql, но прочитав одну книгу Гроффа других вариантов не нашел


 
Sergey13 ©   (2007-10-08 16:15) [3]

> [2] xayam ©   (08.10.07 16:12)

А других вариантов и нет по большому счету. Запрос по поиску подстроки по любому затратная штука.


 
Desdechado ©   (2007-10-08 16:32) [4]

Есть и другие варианты, но в FB их нужно делать руками, тогда как в других СУБД часто есть встроенные механизмы.
Например, можно разбить текст на слова, соотнести слова с постом, проиндексировать таблицу слов и искать по ним. Но здесь тоже не очень удобно, т.к. только целые слова и только в тех формах, какие есть в тексте. Но уже лучше, чем простой LIKE.


 
Desdechado ©   (2007-10-08 16:34) [5]

Кстати
в параметрах бд: кеш, sweep interval, размер страницы, индексы
размер страницы действительно влияет на скорость чтения данных и работы с индесками. Меньше 4 кб ставить не рекомендую.


 
xayam ©   (2007-10-08 16:36) [6]


> Sergey13 ©   (08.10.07 16:15) [3]
> > [2] xayam ©   (08.10.07 16:12)
> А других вариантов и нет по большому счету. Запрос по поиску
> подстроки по любому затратная штука.

это понятно, хотя вот у меня на работе бд несколько миллионов записей ищет достаточно быстро, правда там Sql Server, а тут записей на порядок меньше и такие тормоза ((


 
Sergey13 ©   (2007-10-08 16:37) [7]

> [5] Desdechado ©   (08.10.07 16:34)

Вроде размер страницы (желательно) должен соответствовать (или быть кратным) размеру кластера на диске.


 
Sergey13 ©   (2007-10-08 16:38) [8]

> [6] xayam ©   (08.10.07 16:36)
> это понятно, хотя вот у меня на работе бд несколько миллионов
> записей ищет достаточно быстро
Такой же запрос?


 
xayam ©   (2007-10-08 16:40) [9]


> Sergey13 ©   (08.10.07 16:38) [8]
> > записей ищет достаточно быстро
> Такой же запрос?

незнаю, я там не админю))


 
Sergey13 ©   (2007-10-08 16:50) [10]

> [9] xayam ©   (08.10.07 16:40)

Есть поиск и есть поиск. Одно дело искать по like UPPER("%ччч%") и другое дело поиск по индексу. Инвалидная коляска и феррари.


 
xayam ©   (2007-10-08 17:07) [11]


> Desdechado ©   (08.10.07 16:32) [4]
> Например, можно разбить текст на слова, соотнести слова
> с постом, проиндексировать таблицу слов и искать по ним.
>  Но здесь тоже не очень удобно, т.к. только целые слова
> и только в тех формах, какие есть в тексте

да это тоже плохо


 
Desdechado ©   (2007-10-08 17:10) [12]

> Sergey13 ©   (08.10.07 16:37) [7]
Да, страница должна быть равна или вмещать целое число кластеров. Тогда не будет "холостых чтений" диска.
И чем больше размер страницы, тем меньше глубина индекса на большой таблице. При глубине >3 возникают заметные тормоза.


 
Desdechado ©   (2007-10-08 17:11) [13]

> да это тоже плохо
Уже успел попробовать?


 
xayam ©   (2007-10-08 17:17) [14]


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

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

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


 
Desdechado ©   (2007-10-08 17:21) [15]

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


 
xayam ©   (2007-10-11 13:49) [16]

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


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

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

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

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

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


 
xayam ©   (2007-10-11 14:06) [18]


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

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


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

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


 
xayam ©   (2007-10-11 15:53) [20]


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

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


 
Desdechado ©   (2007-10-11 16:42) [21]

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


 
xayam ©   (2007-10-15 16:09) [22]


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

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


 
xayam ©   (2007-10-16 15:24) [23]


> Desdechado ©

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


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

up


 
Desdechado ©   (2007-10-19 13:49) [25]

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

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

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


 
Sergey13 ©   (2007-10-19 14:05) [26]

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

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


 
xayam ©   (2007-10-19 14:15) [27]


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

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

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

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


 
xayam ©   (2007-10-19 14:31) [28]

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


 
xayam ©   (2007-10-19 15:55) [29]

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

> Desdechado

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


 
xayam ©   (2007-10-19 18:20) [30]

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


 
Desdechado ©   (2007-10-19 19:10) [31]

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

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


 
xayam ©   (2007-10-19 19:23) [32]


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

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


 
xayam ©   (2007-10-20 17:26) [33]


> 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;



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

Текущий архив: 2007.11.11;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.02 c
15-1191606767
mp5k
2007-10-05 21:52
2007.11.11
Открытие *.rar файлов в проводнике?


9-1162993242
dfsfwe
2006-11-08 16:40
2007.11.11
DelphiX


2-1192797770
Neo
2007-10-19 16:42
2007.11.11
поиск топ100


15-1191917876
031178
2007-10-09 12:17
2007.11.11
Компоненты


15-1191818370
MultIfleX
2007-10-08 08:39
2007.11.11
реализация RSA