4.9.MySQL 协议支持与 SphinxQL
优质
小牛编辑
134浏览
2023-12-01
Sphinx的searchd守护程序从 版本0.9.9-rc2开始支持MySQL二进制网络协议,并且能够通过标准的MySQL API访问。例如,“mysql”命令行程序可以很好地工作。以下是用MySQL客户端对Sphinx进行查询的例子:
$ mysql -P 9306 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 0.9.9-dev (r1734) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SELECT * FROM test1 WHERE MATCH('test') -> ORDER BY group_id ASC OPTION ranker=bm25; +------+--------+----------+------------+ | id | weight | group_id | date_added | +------+--------+----------+------------+ | 4 | 1442 | 2 | 1231721236 | | 2 | 2421 | 123 | 1231721236 | | 1 | 2421 | 456 | 1231721236 | +------+--------+----------+------------+ 3 rows in set (0.00 sec)
请注意mysqld甚至根本没有在测试机上运行。所有事情都是searchd自己搞定的。
新的访问方法是对原生API的一种补充,原生API仍然完美可用。事实上,两种访问方法可以同时使用。另外,原生API仍旧是默认的访问方法。MySQL协议支持需要经过额外的配置才能启用。当然这只需要更动一行配置文件,加入一个协议为mysql41的监听器(listener)就可以了:
listen = localhost:9306:mysql41
如果仅仅支持这个协议但不支持SQL语法,那没什么实际意义。因此Sphinx现在还支持SQL的一个很小的子集,我们给这个子集起个绰号,叫SphinxQL。目前已经实现的语句有:
- SELECT
- SHOW WARNINGS
- SHOW STATUS
- SHOW META
SELECT语句,语法仿照标准SQL,但有一些Sphinx特有的扩展,也缺少一些标准SQL的特性(比如(目前)不支持JOIN)。具体地说:
- 列列表子句。列名、任意表达式以及星号(“*”)都允许出现在列列表中(即“SELECT @id, group_id*123+456 FROM test1”是合法的)。与标准SQL不同,任何计算出的表达式都必须有一个有效的标识符作为别名。目前,特殊名称必须有一个前导的“at”符号(@), 例如@id和@weight。这个限制未来会被放宽。.
- • FROM子句。FROM子句列举了要从哪些索引中进行搜索。与标准SQL不同,逗号的意思类似它在Query()API调用中的意思,代表全文索引的枚举,而不代表JOIN。
- • WHERE子句。这个子句的内容既可以对应到全文查询,也可以对应过滤器。比较操作符(=, !=, <, >, <=, >=)、IN()、AND、NOT和BETWEEN等都被支持,她们直接映射成过滤器。而OR操作符尚未得到支持,但未来会支持。支持 MATCH(‘query’)这种形式,它被映射成一个全文查询。系统按照全文查询规则理解查询。在WHERE子句中最多只能有一个MATCH()。
- • GROUP BY子句。目前仅支持根据一个列进行分组, 但这个列可以是一个计算出来的表达式。
SELECT *, group_id*1000+article_type AS gkey FROM example GROUP BY gkey
系统支持将聚集函数(AVG(),MIN(),MAC(),SUM())用在列列表子句中。这些聚集函数的参数既可以是简单的属性也可以是任意表达式。 COUNT(*)被隐含支持,因为使用GROUP BY就会导致@count这列自动被包括在结果集合中。未来可能会添加显式的支持。COUNT(DISTINCT attr)也被支持。目前每个查询中至多只能有一个COUNT(DISTINCT),而且参数必须是属性。这两种限制未来都可能被放宽。SELECT *, AVG(price) AS avgprice, COUNT(DISTINCT storeid) FROM products WHERE MATCH('ipod') GROUP BY vendorid
- WITHIN GROUP ORDER BY子句。这个子句是Sphinx引入的,它使我们可以控制一个分组中最优的行是怎样选出的。这个自己的语法跟标准的ORDER BY子句相同:
SELECT *, INTERVAL(posted,NOW()-7*86400,NOW()-86400) AS timeseg FROM example WHERE MATCH('my search query') GROUP BY siteid WITHIN GROUP ORDER BY @weight DESC ORDER BY timeseg DESC, @weight DESC
- ORDER BY子句。不同于标准SQL,只能根据列名(而不是表达式)排序,必须显式地写明ASC(升序)或者DESC(降序)。不过列名可以是通过表达式计算出来的。
SELECT *, @weight*10+docboost AS skey FROM example ORDER BY skey
- LIMIT子句。支持LIMIT N和LIMIT M,N两种格式。与标准SQL不同(但是就像在Sphinx API中那样),默认有个隐含的LIMIT 0,20。
- • OPTION子句。这是Sphinx引入的特殊扩展,它使我们可以设置一些只影响一个查询的选项。语法如下:
OPTION <optionname>=<value> [ , ... ]
支持设置的选项和允许设置的值如下:- 'ranker' - 以下值之一 'proximity_bm25', 'bm25', 'none', 'wordcount', 'proximity', 'matchany', 或者 'fieldmask'
- 'max_matches' - 整数(当前查询的最大匹配数目)
- 'cutoff' - 整数(最大匹配数阈值)
- 'max_query_time' - 整数(最大搜索时间阈值,毫秒)
- 'retry_count' - 整数(分布式重试数目)
- 'retry_delay' - 整数(分布式重试的延迟时间,毫秒)
SELECT * FROM test WHERE MATCH('@title hello @body world') OPTION ranker=bm25, max_matches=3000
SHOW WARNINGS语句,用于获取上一条查询产生的警告信息。返回的信息还包括该查询本身:
mysql> SELECT * FROM test1 WHERE MATCH('@@title hello') \G ERROR 1064 (42000): index test1: syntax error, unexpected TOK_FIELDLIMIT near '@title hello' mysql> SELECT * FROM test1 WHERE MATCH('@title -hello') \G ERROR 1064 (42000): index test1: query is non-computable (single NOT operator) mysql> SELECT * FROM test1 WHERE MATCH('"test doc"/3') \G *************************** 1. row *************************** id: 4 weight: 2500 group_id: 2 date_added: 1231721236 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS \G *************************** 1. row *************************** Level: warning Code: 1000 Message: quorum threshold too high (words=2, thresh=3); replacing quorum operator with AND operator 1 row in set (0.00 sec)
SHOW STATUS语句,显示一些很有用的性能计数器。仅当searchd
启动时带有--iostats
和--cpustats
开关时,IO和CPU计数器才分别可用。
mysql> SHOW STATUS; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | uptime | 216 | | connections | 3 | | maxed_out | 0 | | command_search | 0 | | command_excerpt | 0 | | command_update | 0 | | command_keywords | 0 | | command_persist | 0 | | command_status | 0 | | agent_connect | 0 | | agent_retry | 0 | | queries | 10 | | dist_queries | 0 | | query_wall | 0.075 | | query_cpu | OFF | | dist_wall | 0.000 | | dist_local | 0.000 | | dist_wait | 0.000 | | query_reads | OFF | | query_readkb | OFF | | query_readtime | OFF | | avg_query_wall | 0.007 | | avg_query_cpu | OFF | | avg_dist_wall | 0.000 | | avg_dist_local | 0.000 | | avg_dist_wait | 0.000 | | avg_query_reads | OFF | | avg_query_readkb | OFF | | avg_query_readtime | OFF | +--------------------+-------+ 29 rows in set (0.00 sec)
SHOW META语句,显示关于上一条查询的一些额外的元信息(meta-information),比如查询时间和关于关键词的统计信息:
mysql> SELECT * FROM test1 WHERE MATCH('test|one|two'); +------+--------+----------+------------+ | id | weight | group_id | date_added | +------+--------+----------+------------+ | 1 | 3563 | 456 | 1231721236 | | 2 | 2563 | 123 | 1231721236 | | 4 | 1480 | 2 | 1231721236 | +------+--------+----------+------------+ 3 rows in set (0.01 sec) mysql> SHOW META; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | total | 3 | | total_found | 3 | | time | 0.005 | | keyword[0] | test | | docs[0] | 3 | | hits[0] | 5 | | keyword[1] | one | | docs[1] | 1 | | hits[1] | 2 | | keyword[2] | two | | docs[2] | 1 | | hits[2] | 2 | +---------------+-------+ 12 rows in set (0.00 sec)