Задать вопрос

Как увеличить скорость поиска в sphinx?

Имеется база данных MySQL, размером 200 Гб. 4 млрд текстовых записей + ID (AUTO_INCREMENT).
Если делать простой запрос LIKE '%%', то он длится примерно 10 часов.
Я поставил Sphinx, проиндексировал, получилось 600 ГБ индекс(пришлось покупать еще один HDD). Теперь запрос идет от 5 до 10 минут. Все равно долго. Сейчас база поделена шарды, каждый шард по 32 млн документов(почему-то ограничение в 4 ГБ на 1 индекс).
Подскажите, кто в теме, что можно подкрутить, чтобы увеличить скорость поиска?
Конфиг файл:
#!/usr/bin/php
<?php
$nPerShard = 32*1000*1000;//32M
$shardCount = 120;
for ($i=0; $i<$shardCount; ++$i) { $first = $i*$nPerShard; $last = $first+$nPerShard; 
?>
source shard<?=$i?>
{
	type			= mysql

	sql_host		= localhost
	sql_user		= root
	sql_pass		= пароль
	sql_db			= база
	sql_port		= 3306

	sql_query_pre		= SET NAMES utf8

	sql_query		= SELECT ID, TEXT FROM таблица WHERE ID >= <?= $first ?> AND ID < <?= $last ?>

	sql_field_string	= TEXT
}

index idx_eng_keywords<?=$i?>
{
	source			= shard<?=$i?>

        wordforms		= /home/***/***/wordforms/en.txt
	path			= /media/***/c2dcfc1c-1656-4f82-b9fb-64a22058a278/eng-keywords-idx.<?=$i?>

#https://habrahabr.ru/post/147745/
	expand_keywords		= 1
	index_exact_words	= 1
}

<?php
}
?>


index index_main
{
	type           		= distributed

<?php for ($i=0; $i<$shardCount; ++$i) { ?>
	local			= idx_eng_keywords<?=$i?>

<?php } ?>

}


indexer
{
	mem_limit 		= 1024M
}


searchd
{
	listen			= 9312
	listen			= 9306:mysql41
	log			= /home/bogdan/poisk/sph/var/log/searchd-k.log
	query_log		= /home/bogdan/poisk/sph/var/log/query-k.log
	binlog_path		= # disable logging
	read_timeout		= 5
	max_children		= 30
	pid_file		= /home/bogdan/poisk/sph/var/log/searchd-k.pid
	seamless_rotate		= 1
	preopen_indexes		= 1
	unlink_old		= 1
	workers			= threads # for RT to work
	binlog_path		= /home/bogdan/poisk/sph/var/data
	dist_threads		= 8
}

* - файл словоформ весит 1.8 Мб.
Пример запроса, который производится (sphinxql):
SELECT * FROM index_main WHERE MATCH('test');
P.s. хотелось бы получать ВСЕ результаты поиска за 10 и меньше секунд, а не за 5 минут, как сейчас.
Информация о машине:
AMD процессор 8 ядер по 4 ГГц, 8 Гб памяти, 3 жестких диска(2 HDD: 320gb, 750gb; 1 SSD: 120gb),
Debian Linux 8.8.

===========
root@debian:/home/bogdan/poisk/sph/bin# hdparm -Tt /dev/sdc

/dev/sdc:
 Timing cached reads:   4440 MB in  2.00 seconds = 2220.46 MB/sec
 Timing buffered disk reads:  14 MB in  3.12 seconds =   4.49 MB/sec
root@debian:/home/bogdan/poisk/sph/bin# hdparm -Tt /dev/sdc

/dev/sdc:
 Timing cached reads:   5266 MB in  2.00 seconds = 2633.95 MB/sec
 Timing buffered disk reads:   8 MB in  3.45 seconds =   2.32 MB/sec
root@debian:/home/bogdan/poisk/sph/bin#


UPD 2 Jul 2017:
Убрал из конфига "sql_field_string = TEXT", поле в выборке(результате поиска) пропало, т.е. только айди выдает, но размер индекса стал 70 Гб. Время поиска 1 секунда на HDD, 0.4 сек на SSD.
Кто-то может объяснить, зачем нужен sql_field_string??
  • Вопрос задан
  • 2998 просмотров
Подписаться 12 Сложный 8 комментариев
Решение пользователя crazy_racoon К ответам на вопрос (5)
@crazy_racoon
все просто, ты использовал конструкцию, sql_field_string = TEXT, то есть ты добавил все поля из базы из этой колонки в поиск, соответственно поиск все засунул без изменений в индекс, и он стал жирным. убирай это. сделай поиск без этого, а уже результаты цепляй из базы, получится один запрос в базу со всем твоим текстом, весить будет гроши. то есть, сфинкс при ответе выдает, учитывая офсет и лимит записи в поиске, именно те поля которые ты указал в конфиге, типа ид прайс и тд, в данном случае еще и текст. лишнего он выдавать не должен, искать да, но не выдавать. Соответственно делаешь запрос к сфинксу, потом из его хитов вылавливаешь айдишники и цепляешь к ним запрос из бд.
Ответ написан
Комментировать