2015-01-21 5 views
2

Мы используем индексы реального времени Sphinx и разговариваем с ними через PHP-драйвер mysqli. Одиночные запросы работают нормально, но мы пытаемся реализовать пакетный процесс обновления с помощью multi_query.multi_query не работает в mysqli для обновления индекса sphinx в реальном времени с помощью sphinxql

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

UPDATE rt SET rank = 1 WHERE id = 881523; 
UPDATE rt SET rank = 2 WHERE id = 881727; 
UPDATE rt ... 

(это после того, как взрывается с точкой с запятой, разрывы строк добавлены для удобства чтения)

И ошибки мы получаем:

sphinxql: syntax error, unexpected ';', expecting $end near ';UPDATE rt SET rank = 2 WHERE id = 881727' 

Если я копирую/вставляю запрос в клиент CLI mysql, нет проблем:

mysql> UPDATE rt SET rank = 1 WHERE id = 881523;UPDATE rt SET rank = 2 WHERE id = 882884;UPDATE rt SET rank = 3 WHERE id = 881727; 
Query OK, 1 row affected (0.01 sec) 

Query OK, 1 row affected (0.01 sec) 

Query OK, 1 row affected (0.01 sec) 

Вот код PHP. $conn является экземпляром класса Connection из http://foolcode.github.io/SphinxQL-Query-Builder/, но мы работаем с базовой связью Mysqli непосредственно с помощью $conn->getConnection():

$query = implode(';', $queries); 
if($conn->getConnection()->multi_query($query)) { 
     do { } 
     while($conn->getConnection()->next_result()); 
} 
if($conn->getConnection()->error) { 
     error_log("query: " . $query); 
     error_log($conn->getConnection()->error); 
     die(); 
} 

Я попытался с помощью multiQuery() функции из соединения класса SphinxQL Query Builder с такие же результаты.

Сообщение об ошибке, указывающее на точку с запятой, неожиданно кажется самой странной для меня частью. Если он хочет $ end, значит ли это, что он не поддерживает несколько запросов? Почему бы и нет, если он хочет взять тот же запрос через клиент mysql?

$php -v 
PHP 5.5.20 (cli) (built: Dec 29 2014 18:02:29) 
Copyright (c) 1997-2014 The PHP Group 
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies 
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies 
+0

Я вижу, что вы используете 'implode()', но после взлома вы добавляете '' 'в конце' $ query' для завершения строки SQL? –

+0

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

+0

Рассматривали ли вы использование подготовленного заявления и просто повторение обновлений? Я предполагаю, что вы получите лучшую производительность таким образом, так как запрос не нужно перепланировать каждый раз. –

ответ

1

Итак, в настоящее время (версия 2.2.7) документы (http://sphinxsearch.com/docs/current/sphinxql-multi-queries.html) указывают, что поддержка нескольких запросов предназначена только для запросов SELECT, SHOW WARNINGS, SHOW STATUS и SHOW META. Это объясняет, почему sphinx ожидает завершения запроса, а не ';' для запросов UPDATE.

Барри предложил мне на форумах sphinx (http://sphinxsearch.com/forum/view.html?id=13201) использовать функцию UpdateAttributes API-интерфейса sphinx (http://sphinxsearch.com/docs/current.html#api-func-updateatttributes) для обработки массовых обновлений. Это работало очень хорошо. Мы видим 5k обновлений/секунду для двух разных индексов (те же данные, индексированные двумя разными способами) в одном потоке нашего оборудования EC2 (r3.xlarge, индексы на эфемерном SSD).

2

сообщение об ошибке вы получаете, от сервера Searchd, потому что не ожидать несколько команд conncateted с;

Запрос работает в CLI, так как сам клиент mysql сам разбивает его на отдельные запросы и отправляет их один за другим на сервер (см. Опцию разделителя). https://mariadb.com/kb/en/mariadb/documentation/clients-and-utilities/mysql-client/delimiters-in-the-mysql-client/

MySQLi, имеет аналогичную функцию запроса http://php.net/manual/en/mysqli.multi-query.php который жестко для использования; по всей видимости. Оказывается, что sphinx не поддерживает его для запросов UPDATE, только для запросов - см. Комментарий к основному вопросу.

+0

Я не уверен, что понимаю смысл, который вы пытаетесь сделать в отношении многозадачной функции mysqli. вы говорите, что он способен раскалывать сами запросы и отправлять их по одному или просто повторять, что он не может дать сфинксу то, что он ожидает? –

+0

Предполагая, что sphinx не может обрабатывать запросы, разделенные точкой с запятой, что, похоже, имеет место, есть способ поместить mysqli в режим, где он может быстро запускать кучу запросов для обработки, не дожидаясь очереди в оба конца ? Если мы выполняем эти запросы один за другим, это занимает очень много времени. –

+0

В основном я объяснял ПОЧЕМУ CLI работает. Но также сказать, что multi_query mysqli ДОЛЖЕН работать. Я не могу объяснить, почему он не работает для вас. Но опять же я использовал только multi_query для выполнения нескольких операторов выбора, никогда не добавляя многократных обновлений. – barryhunter