2015-12-25 3 views
1

Я делаю указатель на столе с ~ 90 000 000 строк. Полнотекстовый поиск должен быть выполнен в поле varchar, которое называется email. Я также установил parent_id в качестве атрибута.Запрос Sphinx занимает слишком много времени

Когда я запускаю запросы для поиска сообщений электронной почты, которые соответствуют словам с небольшим количеством хитов, они увольняют сразу:

mysql> SELECT count(*) FROM users WHERE MATCH('diedsmiling'); 
+----------+ 
| count(*) | 
+----------+ 
|  26 | 
+----------+ 
1 row in set (0.00 sec) 

mysql> show meta; 
+---------------+-------------+ 
| Variable_name | Value  | 
+---------------+-------------+ 
| total   | 1   | 
| total_found | 1   | 
| time   | 0.000  | 
| keyword[0] | diedsmiling | 
| docs[0]  | 26   | 
| hits[0]  | 26   | 
+---------------+-------------+ 
6 rows in set (0.00 sec) 

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

mysql> SELECT count(*) FROM users WHERE MATCH('mail'); 
+----------+ 
| count(*) | 
+----------+ 
| 33237994 | 
+----------+ 
1 row in set (9.21 sec) 

mysql> show meta; 
+---------------+----------+ 
| Variable_name | Value | 
+---------------+----------+ 
| total   | 1  | 
| total_found | 1  | 
| time   | 9.210 | 
| keyword[0] | mail  | 
| docs[0]  | 33237994 | 
| hits[0]  | 33253762 | 
+---------------+----------+ 
6 rows in set (0.00 sec) 

Использование parent_id атрибута, не дает никакой прибыли:

mysql> SELECT count(*) FROM users WHERE MATCH('mail') AND parent_id = 62003; 
+----------+ 
| count(*) | 
+----------+ 
| 21404 | 
+----------+ 
1 row in set (8.66 sec) 

mysql> show meta; 
+---------------+----------+ 
| Variable_name | Value | 
+---------------+----------+ 
| total   | 1  | 
| total_found | 1  | 
| time   | 8.666 | 
| keyword[0] | mail  | 
| docs[0]  | 33237994 | 
| hits[0]  | 33253762 | 

Вот мои сфинкс конфига:

source src1 
{ 
    type   = mysql 
    sql_host  = HOST 
    sql_user  = USER 
    sql_pass  = PASS 
    sql_db   = DATABASE 
    sql_port  = 3306 # optional, default is 3306 

    sql_query  = \ 
      SELECT id, parent_id, email \ 
       FROM users 

    sql_attr_uint = parent_id  

}  

index test1 
{  
    source   = src1 
    path   = /var/lib/sphinx/test1 

} 

Запроса, который мне нужно запустить выглядит следующим образом:

SELECT * FROM users WHERE MATCH('mail') AND parent_id = 62003; 

мне нужно, чтобы получить все сообщения электронной почты, которые соответствуют определенной работе и имеет определенную parent_id.


Мои вопросы: Есть ли способ оптимизировать ситуацию, описанную выше? Может быть, есть более удобный режим сопоставления для такого типа запросов? Если я перейду на сервер с SSD-дисками, будет ли рост производительности значительным?

ответ

1

Просто чтобы получить счет может просто сделать

Select id from index where match(...) limit 0 option ranker=none; show meta; 

И получить от total_found.

Будет намного эффективнее, чем count [*), который вызывает группу.

Или даже call keywords('word','index',1); если только один слова.

+0

Спасибо. Фактически, запрос, который мне нужно запустить, выглядит так: 'SELECT * FROM users WHERE MATCH ('mail') AND parent_id = 62003;'. Мне нужно получить все электронные письма, соответствующие определенной работе, и иметь определенный «parent_id». –

+0

Итак? Такая же идея должна по-прежнему работать. Использование 'total_found' более эффективно, чем использование COUNT (*)' - ранжирования или даже результатов, которые не нужны. – barryhunter

+0

Хотя, если производительность действительно проблема, возможно, использование поля (а не атрибута) может быть немного быстрее. Он может использовать доклистов для ответа на запрос. 'MATCH ('mail @parent 62003')' – barryhunter