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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.063 c
15-1191581507
s_t_d
2007-10-05 14:51
2007.11.11
BIOS для MotherBoard VERTEX M1 94V-0


2-1193040297
ruma
2007-10-22 12:04
2007.11.11
TStringGrid. Как удержать фокус на ячейке таблицы?


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


2-1192536340
Kolan
2007-10-16 16:05
2007.11.11
Variant := := StrToInt( 1 ) приводит к исключению, почему?


2-1192472919
Elec3C
2007-10-15 22:28
2007.11.11
Проблемка с динамическим массивом





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