Дельта индексы необходимы для того, чтобы не индексировать базу полностью в течении короткого времени, а использовать маленький индекс.
К примеру, мы имеем очень много записей в базе данных, сотни тысяч или несколько миллионов записей, и данные поступают очень часто, нам их необходимо индексировать, однако запускать каждые 5-10 минут индексацию — это слишком трудоемко.
Поэтому мы делаем два индекса:
- Полный — индексируются все данные целиком (запускаем раз в сутки)
- Дельта — индексируется только малая часть данных, добавленных в течении дня (запускаем каждые 5-10 минут)
Но как определять с какого момента индексировать данные в дельта-индексе?
Нам необходимо помнить крайний проиндексированный ид-записи из полного-индекса, и начинать индексировать данные только с него, все очень просто :)
Для этого создадим еще одну таблицу в базе данных, чтобы хранить там ид крайней записи из полного-индекса:
1 2 3 4 | CREATE TABLE `sphinx_delta_counter` ( `index_name` ENUM( 'pyha_forum' ) NOT NULL, `last_post_id` INT UNSIGNED NOT NULL ) ENGINE = InnoDB; |
Где,
- «index_name» — имя индекса, например если у вас много индексов с разных таблиц (можно опустить, если у вас один индекс);
- «last_post_id» — крайний номер записи для конкретного индекса.
Вставим для нашего индекса запись, чтобы потом можно было обновлять счетчик:
1 2 | INSERT INTO `sphinx_delta_counter` SET `index_name` = 'pyha_forum', `last_post_id` = 0; |
Вы конечно можете этот запрос и в индексе сфинкса использовать, предварительно переписав его на «on duplicate key» и добавив уникальный индекс на связку «index_name+last_post_id», однако я думаю это излишне.
Строим индексы в Sphinx
Привожу примерный конфигурационный файл, на примере предыдущей статьи http://adw0rd.ru/2009/smf-sphinx/.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # сорс для подключения к БД, далее его будем наследовать в других сорсах source dbconnect { type = mysql sql_host = localhost sql_user = pyha sql_pass = sql_db = pyha sql_port = 3306 sql_sock = /tmp/mysql.sock } # сорс полного-индекса source pyha_forum : dbconnect { sql_query_pre = SET NAMES utf8 sql_query_pre = SET CHARACTER SET utf8 # обновляем наш счетчик, добавляем туда крайний ид записи для дельта-индекса sql_query_pre = \ update sphinx_delta_counter \ set last_post_id = (select max(ID_MSG) from smf_messages) \ where index_name = 'pyha_forum'; # выбираем все данные для полного-индекса sql_query = \ select ID_MSG, concat('user:',posterName) as posterName, subject, body \ from smf_messages; sql_query_info = select ID_MSG, posterName, subject, body from smf_messages where ID_MSG = $id sql_ranged_throttle = 0 } # сорс дельта-индекса source pyha_forum_delta : dbconnect { sql_query_pre = SET NAMES utf8 sql_query_pre = SET CHARACTER SET utf8 # выбираем только те данные, которые появились после проиндексации полного-индекса sql_query = \ select ID_MSG, concat('user:',posterName) as posterName, subject, body \ from smf_messages \ where ID_MSG > (select last_post_id from sphinx_delta_counter where index_name = 'pyha_forum'); sql_query_info = select ID_MSG, posterName, subject, body from smf_messages where ID_MSG = $id sql_ranged_throttle = 0 } # полный-индекс index pyha_forum { source = pyha_forum path = /var/sphinxsearch/pyha_forum docinfo = extern mlock = 0 morphology = stem_enru min_word_len = 2 charset_type = utf-8 charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F min_infix_len = 2 enable_star = 1 } # дельта-индекс index pyha_forum_delta : pyha_forum { source = pyha_forum_delta path = /var/sphinxsearch/pyha_forum_delta } # настройки индексатора indexer { mem_limit = 32M } # настройки поискового демона searchd { address = 127.0.0.1 port = 3312 log = /var/sphinxsearch/log/searchd.log query_log = /var/sphinxsearch/log/query.log read_timeout = 5 max_children = 30 #pid_file = /var/sphinxsearch/log/searchd.pid max_matches = 1000 } |
Ну вот и все, сфинкс настроен, далее поставим переиндексацию в крон.
Ставим в крон
1 2 | 0 1 * * * /usr/local/bin/indexer --config /usr/local/etc/sphinx.conf.sh pyha_forum --rotate > /dev/null */5 * * * * /usr/local/bin/indexer --config /usr/local/etc/sphinx.conf.sh pyha_forum_delta --rotate > /dev/null |
Где,
- Индексировать полный-индекс каждый день в час ночи
- Индексировать дельта-индекс каждые пять минут
Не понятно что за конфиг «/usr/local/etc/sphinx.conf.sh»?
Тогда, читаем статью Инклуд конфигов Sphinx.
Добавим поиск по дельта-индексу в код
Так как я использую SphinxSE, то добавить надо так:
Тогда будет производится поиск по полному- и дельта-индексам!
Встраиваем в SMF
Далее, раз мы разбираем пример на основе статьи http://adw0rd.ru/2009/smf-sphinx/, то снова найдем код в «/Source/Search.php» (строка ~1377):
1 2 3 4 5 6 7 | $request = db_query( "SELECT `sm`.`ID_TOPIC`, `ssm`.`id` AS `ID_MSG`, 1000 AS `relevance`, 0 AS `num_matches` FROM `sphinx_smf_messages` AS `ssm` LEFT JOIN `smf_messages` AS `sm` ON `ssm`.`id` = `sm`.`ID_MSG` WHERE `ssm`.`query` = '".$context['search_params']['search'].";weights=1,2,3' LIMIT " . (int) $_REQUEST['start'] . ", $modSettings[search_results_per_page]", __FILE__, __LINE__); |
заменим на
1 2 3 4 5 6 7 | $request = db_query( "SELECT `sm`.`ID_TOPIC`, `ssm`.`id` AS `ID_MSG`, 1000 AS `relevance`, 0 AS `num_matches` FROM `sphinx_smf_messages` AS `ssm` LEFT JOIN `smf_messages` AS `sm` ON `ssm`.`id` = `sm`.`ID_MSG` WHERE `ssm`.`query` = '".$context['search_params']['search'].";weights=1,2,3;index=pyha_forum,pyha_forum_delta' LIMIT " . (int) $_REQUEST['start'] . ", $modSettings[search_results_per_page]", __FILE__, __LINE__); |
Ну вот и все :)



Что вы так боитесь использовать слово последний? суеверия =)
Я служил в Военно-Морской Авиации, там слово «последний» — нет, потомучто «последний вылет». Вот там из меня и выбили это слово ;)
а ларчик просто открывался... Спасибо за информацию))
удобно проиндексировать только часть страницы, которая тебе нужна и на выходе получить максимальный результат
Хочу посоветоваться. Есть ли смысл создавать дельта индексы, если полная индексация системы происходит примерно за 3-4 минуты?
думаю нет, по крайней мере я бы не заморачивался...
хотя если вам надо индексировать каждую минуту, то можно подумать о дельте...
У вас ротейт идет 3-4 минуты?
Доброе время суток, я вот делал по такому алгоритму строю дельта индекс, там появились новые индексы, потом добавляю их в основной индекс с помощью --merge , в принципе все отлично, но хотел бы Вас спросить можно ли как то удалять индексы из дельта индекса после слияния в основной ? заранее всех благодарю!
Спасибо разобрался! :)
Elvis, как решили?
Разве счётчик нада обновлять не в сорсе дельта индекса ?
Grind, а на основании чего вы так решили?
Предпологал, что после каждой дельта индексации происходит изменение индекса, для последующей индексации от этого id.
>Предпологал, что после каждой дельта индексации происходит изменение индекса
происходит изменение именно дельта-индекса, а не основного, в это вся суть, чтобы не нагружать основной.
А вот после индексации основного-индекса запоминается максимальный проиндексированный ид, и с него начинает дельта-индекс индексировать данные