![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Производительность [IB6.x]
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]
> > да это тоже плохо
> Уже успел попробовать?
нет конечно))
в смысле плохо что
> только целые слова
> и только в тех формах, какие есть в тексте