![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| Usya |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Задача стоит следующим образом: есть около сотни *.csv-файлов (с разной структурой) общим объемом порядка 250 тыс. строк. Необходимо организовать поиск по ним. На данный момент если поиск осуществляется по одному слову, то он занимает в среднем порядка 3-7 сек, иногда доходит до 15 (в зависимости от загруженности сервера). Хотя бывают случаи, когда на поиск уходит 30-60 сек (При очень больших тормозах на серваке. Такое бывает достаточно редко, но пользователям же не объяснишь все эти нюансы, когда они заходят на сайт).
Как сократить время, затрачиваемое на поиск? Буду признателен за любой совет или ссылку. --------------------
Я не волшебник, я только учусь... |
|||
|
||||
| Usya |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
А в ответ тишина...
Неужели никто не работал с большим объемом данных и не пытался сократить время на поиск? Меня интересуют любые нюансы, позволяющие хоть мало-мальски ускорить процесс поиска ключевых слов в текстовом файле. Какие функции и приемы стоит использовать, а какие нет? Хоть что-нибудь... --------------------
Я не волшебник, я только учусь... |
|||
|
||||
| sharq |
|
|||
![]() Perl Liker ![]() ![]() Профиль Группа: Участник Сообщений: 841 Регистрация: 13.12.2004 Где: Ростов-на-Дону Репутация: 2 Всего: 28 |
Usya можно попробавать многопоточность, чтобы одновременно несколько файлов просматривалось.
-------------------- [color=gray]There's More Than One Way To Do It[/color] |
|||
|
||||
| Usya |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Спасибо
Надо попробовать. Хотя, честно говоря, никогда не имел с этим дело. Просто не доводилось Придется разбираться Получится или нет - напишу... --------------------
Я не волшебник, я только учусь... |
|||
|
||||
| Kiber_rat |
|
|||
![]() MACMANIAC ![]() ![]() Профиль Группа: Участник Сообщений: 276 Регистрация: 18.4.2002 Где: Ashdod, Israel Репутация: 1 Всего: 9 |
Я бы предложил сделать систему индексации. Запускать индексирование файлов по cron-у раз в сутки или раз в N часов (зависит от того, насколько часто обновляются файлы) с невысоким приоритетом, что бы это не влияло на работу сервера в целом.
Можно сделать "инкрементальное" индексирование, если существующие файлы не изменяются, а к ним только добовляются новые. Поиск делать уже по индексу, который хранить, к примеру, в BercklyDB файлах (.dbm). Как именно индексировать решай сам, есть масса вариантов. К примеру таблицы типа: Files --------- id_file file_name (path) Words --------- id_word word Word2File --------- id_word id_file Надеюсь мысль понятна, удачи! -------------------- Best regards! @..@_____Ku6ep =*=______\______KPbIC
|
|||
|
||||
| Usya |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Мысля понятна. За совет спасибо!
Однако мне кажется, что здесь проблем не меньше… Я выше писал, что файлы имеют разную структуру, поэтому под один шаблон их не подгонишь. Если быть конкретнее, то в *.csv-файлах хранятся таблицы с разным количеством столбцов (от 2-х до 14-и). И если можно их загнать в базу, то только в одно поле. Соответственно теряются почти все преимущества работы с БД. Кроме того, в исходных таблицах в *.csv-файлах есть подзаголовки, которые придется выносить в отдельное поле, хотя это не принципиально. Таким образом, окончательно может быть выделено всего три поля - имя файла(и соответствующая ему фирма)+шапка таблицы, подзаголовки и все остальное. При поиске будут учитываться только два последних. Кроме того, желательно, чтобы информация после поиска выдавалась не беспорядочно, а последовательно от одного файла (фирмы) к другому, от одного подзаголовка к др. Т.е. потом придется выполнить сортировку по первым двум полям. А если кто-то решит поприкалываться либо оказать медвежью услугу и введет всего одну букву, например, 'а', то все 250 тыс. записей должны быть отсортированы (честно говоря, не знаю, сколько времени это займет и сколько памяти на серваке это потребует). Хотя, возможно, это решаемо сопоставлением с соответствующим проиндексированным по первым двум полям файлом либо введением дополнительного поля – порядкового номера записи с последующей сортировкой найденных записей по этому полю. И последнее, на данный момент у меня только 250 тыс. записей, но это не предел. Надеюсь, что будет больше как минимум раза в два. Кроме того, здесь приходится учитывать ограничения хостинга на память и загрузку процессора. Честно говоря, пока с этой стороной вопроса не сталкивался, но как бы там не оказалось подводного камня. Возможно, некоторые доводы абсурдны, потому что с базами данных я относительно мало работал, но думаю, что связываться с БД в данном случае не имеет смысла. --------------------
Я не волшебник, я только учусь... |
|||
|
||||
| Kiber_rat |
|
|||
![]() MACMANIAC ![]() ![]() Профиль Группа: Участник Сообщений: 276 Регистрация: 18.4.2002 Где: Ashdod, Israel Репутация: 1 Всего: 9 |
Доводы не абсурдны, но я предлагал тебе не перевод всех файлов в базу, а только индексы хранить в базе. То есть на примере локального поисковика в тех же Форточках ХП
То есть ты с определенной периодичностью запускаешь скрипт который строит индексы по твоим файлам, а потом используешь эти индексы для поиска. К примеру, у тебя есть директория с документацией, в ней хранятся доки в txt формате (plain text). Для того что бы найти нужную доку, скажем по Perl у тебя есть два варианта. Первый - открывать каждый файл, искать в нем слово Perl, если есть добавлять в массив с документами отвечающими запросу, нет - искать дальше. Если я правильно понял, то так у тебя сейчас и работает. Второй путь. Индексируешь файлы. Т.е. открываешь файл и строишь по нему таблицу вида (самый простой вариант) слово - имя файла. Естественно что ты можешь не включать слова типа "а", "и", "!" и т.п. Затем открываешь следующий файл и добавляешь в табличку. В итоге имеешь таблицу вида: perl - perlfaq.txt perl - perlref.txt perl - regexp.txt regular - regexp.txt ... и так далее. Тот пример хранения который я привл раньше лучше, поскольку нет избыточности данных. То есть это будет выглядеть так: Worlds 1 - perl 2 - regular 3 - linux ... --------------------- Files 1 - perlfaq.txt 2 - perlref.txt 3 - regexp.txt ... -------------------- W2F 1 - 1 1 - 2 1 - 3 2 - 3 ... Соответственно, на запрос perl мы получим ответ что это слово встречается в 3-х документах. Есть масса алгоритмов индексирования, так что если пороешь в этом направлении наверняка найдешь то что надо. Хочу заметить что на этом принципе работают поисковые системы, а у них, как ты понимаешь, несколько больше чем 250 000 записей ;) -------------------- Best regards! @..@_____Ku6ep =*=______\______KPbIC
|
|||
|
||||
| Usya |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Помимо имен файлов, должны выдаваться все строки (записи), где встречается данное слово (слова). Я мельком упомянул об этом, но не догадался на этом акцентировать внимание
А если пользователь вводит только часть слова? Для каталога прайс-листов как быть при такой индексации, если пользователь не помнит полностью номер модели искомого товара, а только последние четыре цифры из пяти? Кроме того, в исходных файлах может быть куча информации, по которой искать точно не будут (например, столбец цен), но в индексные файлы загонять придется, чтобы не делать дополнительных наворотов на то, что индексировать, а что нет для каждого из файлов с последующим контролем от незапланированных изменений.
Принцип такой, но не все там так просто --------------------
Я не волшебник, я только учусь... |
||||||
|
|||||||
| Guest |
|
||||||||
|
Unregistered |
Можно почитать о принципах построения БД. И идея запихнуть все в БД перестанет быть настолько абсурдной. На вскидку - создай таблицу примерно следующей структуры
Не забывать о здравом смысле
Я бы все же ихал в БД. Причем БД с кешеривоанием запросов. |
||||||||
|
|||||||||
| Usya |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Guest за советы спасибо, но есть несколько но!!!
Насколько я знаю, БД нужны, прежде всего, для устранения избыточности информации. За счет этого можно значительно сократить объем хранимой информации и соответственно ускорить поиск. Плюс дополнительные ускорение, связанное с индексацией. А здесь избыточность изначально практически отсутствует.
Если и придется создавать таблицу, то скорее всего со следующей структурой; id - уникальный номер записи, firma - адрес фирмы+шапка таблицы, pdz - название подзаголовков (категории в прайсах), value - сами записи (позиции прайс-листов), ref - ссылка на следующее поле в этом наборе данных - ??? - возможно и надо - надо подумать.
Минимум два, например, аббревиатура ноутбука (NB), фирмы (HP) и т.д...
А здесь куча вопросов: 1) Стоит ли шкурка выделки? Сильно обрезать исходные данные при переходе к БД не удастся (уже написал почему)... Единственное, в чем принципиальный плюс при переходе к БД, возможно в заточенной процедуре поиска. Но на сколько (или во сколько) это сократит время на поиск в моем случае? Если б знать порядок. Пока что, разбираюсь в распараллеливании процессов в Perl-e. Думую, что из этого можно кое-что полезное выцепить. 2) Какой объем памяти потребуется при использовании БД и какова будет загрузка проца на серваке при простом запросе и при индексации (которую придется делать по хорошему каждые час два по мере обновления прайсов)? На данный момент у меня порядка 20-25 метров инфы, но это не предел. Надеюсь, что будет как минимум раза в два поболее. Как бы ребята из отдела хостинга не попросили пересесть на что-нибудь более легкое, когда уже все будет работать. Это самый главный минус в этой задаче не в пользу БД!!! --------------------
Я не волшебник, я только учусь... |
||||||||
|
|||||||||
| sharq |
|
|||
![]() Perl Liker ![]() ![]() Профиль Группа: Участник Сообщений: 841 Регистрация: 13.12.2004 Где: Ростов-на-Дону Репутация: 2 Всего: 28 |
Usya как ты работаешь с csv-файлами и как ты производишь поиск?
если я сделал правильную догадку по этому поводу, то -------------------- [color=gray]There's More Than One Way To Do It[/color] |
|||
|
||||
| Guest |
|
||||||||||||
|
Unregistered |
БД прежде всего предназначены для _эффективной_ работы с данными. А избыточность информации - эт дело такое... При 1НФ может быть, скорей всего обязана быть
Это ты в каждой записи собираешься тиражировать реквизиты фирмы!?
|
||||||||||||
|
|||||||||||||
| Guest |
|
||||||||||||
|
Unregistered |
Продолжение
Это ты предлагаешь такую структуру, что бы показать насколько избыточна будет твоя инфа, если ее поместить в БД?;)
Чуть подробнее об этом поле. Какая инфа будет лежать в нем?
Я ж говорю, незабывать о здравом смысле вид компьютера - Ноутбуук - десктоп - сервер - и тд Фирма призводитель ИБМ - САН - Ньюлет - и тд. Идея ясна?
Я не совсем понял, где я предлогал "резать" данные?
А эт все от тебя зависит Ну а если серезно, то сейчас глянул на БД одного из своих сайов 117 МБ. 76 000 записей. Поиск по текстовым полям практически не влияет на скорость загрузки страницы. Только здается мне тебе не поиск нужен, а хорошая структура прайс листа. На мой вкус - лучше 4 раза кликнуть мышей, чем набрать некое слово и получить 10 ссылок... |
||||||||||||
|
|||||||||||||
| Usya |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 154 Регистрация: 7.6.2005 Репутация: нет Всего: нет |
Блииииииииин!!! Щас набрал ответ и умудрился его убить
Чтоб не ходить вокруг да около, постараюсь поточнее сформулировать задачу: с ряда сайтов закачиваются прайс-листы и конвертируются в *.csv-формат для дальнейшей обработки. Поисковик при запросе должен выдавать записи последовательно от прайса к прайсу, от позиции к позиции сверху вниз. Кроме того, т.к. прайсы зачастую делают, кто как хочет со своими обозначениями и сокращениями (например, вместо картридж могут быть - к-дж, к/дж, фотокондуктор и т.д., не говоря уже случайной замене русских букв на англ и наоборот), не хочу делать выпадающий список - слишком много геморра. Тем более что в запросе может быть часть номера модели устройства. А на счет здравого смысла - минимальной длины запроса - вполне может быть аббревиатура фирмы из двух букв (чтоб не перебирать все возможные сокращения в названии товара).
Обычная рабочая позиция прайса, например, - Валик структурн 140 желт ОБ;25;60.00.
Как писал выше, структуру исходных прайсов изменить не могу. Приходится иметь дело с тем, что есть. А в БД придется делать таблицы с названиями фирм, реквизитами ...; с подзаголовками в прайсах и сводную с полным перечнем всех позиций прайс-листов.
Я имел ввиду урезать избыточность. Об этом я писал.
Если скорость закачки страницы будет мала, а страница - тяжелая, то так оно и будет Это сообщение отредактировал(а) Usya - 22.8.2005, 23:35 --------------------
Я не волшебник, я только учусь... |
||||||||
|
|||||||||
| sharq |
|
|||
![]() Perl Liker ![]() ![]() Профиль Группа: Участник Сообщений: 841 Регистрация: 13.12.2004 Где: Ростов-на-Дону Репутация: 2 Всего: 28 |
Usya
спасибо за ответ... В общем для работы с csv-файлами существует очень хороший модуль DBD::CSV - драйвер БД CSV для DBI-интерфейса. -------------------- [color=gray]There's More Than One Way To Do It[/color] |
|||
|
||||
![]()
|
| Правила форума "Perl: CGI программирование" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: разработка для Web | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |