Я сейчас пишу WebCrawler, который получит все ссылки на локальные сайты на одном конкретном сайте. Процесс состоит в том, чтобы определить, какие ссылки являются продуктами, и ввести их в мое программное обеспечение для сравнения цен.

Проблема, которую я обнаружил, заключается в том, что я получил неполное сканирование сайта, насчитывающего 5,4 миллиона ссылок. При работе с этими числами сохранение собранных ссылок в памяти в хэш-наборе с последующим сохранением их в простой текстовый файл является доказательством. Хэшсет сильно увеличивает потребление памяти, а у меня всего около 5 гигабайт оперативной памяти.

Каждый раз, когда я получаю новую ссылку, мне нужно проверять, была ли она захвачена раньше. Следовательно, hashset казался самым быстрым способом сделать это сравнение. Из-за проблем с памятью и моих текстовых файлов размером более 1,5 гигабайта я подумал, что лучше переключиться на базу данных - MySQL56. Который я запускаю на Windows 7 64bit, в режиме разработчика.

Я перенес все данные, собранные в базе данных mysql56, используя «ЗАГРУЗИТЬ ЛОКАЛЬНЫЙ ИНФАЙЛ ДАННЫХ», похоже, это сработало, но столбец URL - это просто varchar (400).

Проблема, с которой я столкнулся сейчас, заключается в том, что запрос, чтобы увидеть, присутствует ли URL-адрес в таблице, занимает около 10-15 секунд. Есть ли способ резко улучшить эту производительность.

Одно замечание, которое я пытался установить, - это установить для поля значение unique (с меньшим пределом поля), но при этом база данных, казалось, не отвечала при загрузке данных в файл с 5,4 миллионами записей.

В настоящее время я занимаюсь разработкой на C #, используя SQLconnector.

Я хотел бы знать, могу ли я улучшить производительность этого текстового поля, есть ли альтернативные способы хранения и запроса этих данных.

Благодарность

1
Gregory William Bryant 7 Мар 2014 в 02:11

2 ответа

Лучший ответ

Вы можете изучить использование разделов со структурой таблицы в MySQL. http://dev.mysql.com/doc/refman/5.5 /en/partitioning-types.html

Вы упомянули, что пытались сохранить все данные в памяти, но этого было слишком много. вы можете поместить кэш памяти перед своей базой данных, чтобы получить некоторую производительность. memcached или я думаю, что у MySQL теперь есть собственный.

2
user2691041 7 Мар 2014 в 02:46

У вас есть пара вариантов:

  1. Прежде всего, поставьте на поле индекс. Причина, по которой это занимает 10-15 секунд, заключается в том, что скорее всего выполняется сканирование таблицы, а не сканирование индекса. Вы можете проверить это, посмотрев на план выполнения. Это не обязательно должен быть уникальный индекс (если вы не хотите, чтобы БД отклоняла вставку того же значения).
  2. Еще одна вещь, которую вы можете сделать, - это помочь с поиском по таблице, а также с нехваткой памяти. Вместо того, чтобы хранить в памяти целые URL-адреса, которые могут быть довольно длинными, вычислите MD5 (или любую другую функцию хеширования) для каждого URL-адреса и сохраните его в памяти. Точно так же ain DB вместе с URL-адресом хранит подпись URL-адреса MD5, а затем выполняет поиск по этому значению (также индексированному). Таким образом, нужно будет сравнивать гораздо меньше байтов, и, следовательно, будет быстрее.
  3. Объедините подходы к базе данных и памяти, имея ограниченный кеш в памяти и полное хранилище в БД. Сохраните в памяти ключи MD5 и их возраст (время или FIFO, или расстояние от вашей текущей страницы в графике ссылок веб-сайта). Когда вам нужно проверить ссылку, проверьте кеш памяти. Если попадание, то вы знаете, что посетили URL-адрес. Если кеш отсутствует, только тогда перейдите в базу данных, чтобы действительно увидеть, был ли он посещен. Мы надеемся, что это уменьшит количество запросов к базе данных, которые вам нужно сделать (в действительности это зависит от того, как часто ссылки повторяются).

Другие моменты, которые следует учитывать при оптимизации: 1. На некоторых сайтах есть повторяющиеся ссылки, которые выглядят по-разному, но для ваших целей одинаковы. Примерами могут быть версии для печати, мобильная версия, просмотр отзывов и просмотр цен и т. Д. Вы можете изучить структуру URL-адресов сайта, чтобы узнать, какие из них вам интересны, а какие нет. Выбросьте последние из своей памяти / db. 2. На некоторых сайтах действительно нет ссылок, как в тегах привязки, и вместо этого используется обработка событий JavaScript, чтобы выяснить, является ли что-то кликабельным и как это обработать (например, селекторы jQuery). Вам могут не хватать части сайта, если на нем используются такие методы.

Надеюсь это поможет.

1
LB2 6 Мар 2014 в 22:48