mysql全文索引有个缺点是 经常使用的词汇不会建立索引 而且 不支持中文 ,sphinx提供了比数据库本身更专业的搜索功能。
1高速的建立索引(创建100万条索引只需3~4分钟)
2高性能搜索(一千万条查询速度为毫秒级)
3处理海量数据 (单一索引最大可包含一亿条记录)
4优秀的相关度算法
但是sphinx只支持英文与俄文,这里我们需要另一款软件,coreseek,基于sphinx,添加了中文词库, 专攻中文搜索。
--------------------------------------------------------------------------------------------------------------------------------------------------------------
添加测试数据 ,可以采用蠕虫复制,添加十万条左右数据,看自己电脑配置而定
下载coreseek,解压到软件的盘,如我解压到了f盘
具体的配置信息放在本文最下边了,把相关信息修改即可以,当然我把数据库和数据表都命名了test,修改成自己的,里面的路径修改为自己的软件真实路径。另外注意的是,增量索引需要另建一个a表,示例sql也在文章最后面,建立完a表后,下面就要建立索引了。
先记录下memcached关键词有多少条记录 ==3328条
如果原生sql不建立全文索引的情况下select * like %memcahed%查询,执行很慢。
如果是建立全文索引
memcached查不到,当换一个查询词时,耗时也非常长。
配置文件,以及测试表数据test表 和 记录最大ID的a表(下方附录)准备完成之后,下一步生成索引。
---------------------------------------------------------------------------------------------------------------------------生成索引:
-c是配置文件config的缩写 后面加上sphinx配置里的source名称
建立完成:
此时sphinx.conf里面配置的索引路径下多出了索引文件
--------------------------------------------------------------------------------------------------------------------------------------------
索引生成完毕,下面要开始查询,需安装searchd服务,注意!! 需要超级管理员运行CMD
右键桌面我的电脑--管理--服务
开启完毕;下一步用php来操纵sphinx;
------------------------------------------------------------------------------------------------------------------------------------------------------------
coreseek为我们提供了各种语言的api,
把api文件,放入项目中,我们在sphinxSearch.php中写php代码
代码如何写呢?查找php手册,搜索sphinx
示例代码(下边附录)仅供参考,效果
几乎是瞬间显示,差别是显而易见的。
而且支持中文
目前test表的jobInfo字段已经建立了索引,但是如果有后添加的数据,就需要增量索引了,就是说在原来的索引上增加 新插入的数据的索引。
-----------------------------------------------------------------------------------------------------------------------------------------------
当test表中新增了N条记录时,sphinx会先从a表得到最大id, 只需要增加最大id之后的数据的索引。
为了测试,向test表新增条两条记录
建立增量索引
此时data下多出N多文件
增量索引与原来索引合并
此时看a表的最大ID变为
验证是否加入了索引
到此sphinx的使用基本完事了,其他应用去查手册。当然手动更新增量索引是很low的,window系统可以创建任务计划,linux创建contab定时,定期的执行上面两条增量索引命令就OK了。
end;
-----------------------------------------------------------------------------------------------------------------------------------------------
sphinx.conf配置
#MySQL数据源配置,详情请查看:http://www.coreseek.cn/products-install/mysql/
#源定义
source test
{
type = mysql
sql_host = 127.0.0.1
sql_user = root
sql_pass = root
#对应的数据库
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
#从数据表里查询数据,进行索引的创建
#注意sql语句查询字段必须包括“主键id” jobInfo是test表中需要建立索引的字段
sql_query = select id,jobInfo from test
#在执行完之后执行语句 replace 不存在insert 存在就是update
####注释: 此句是用单独一个表a(a表的实例sql在下边) 记录test表最大的id 以便当test表增加新数据时追加索引 而不是整个表重新创建一遍
sql_query_post = replace into a select 1,max(id) from test;
}
#index定义
index test
{
source = test #注意要对应上面的source名称
# 重要:存储索引的位置 索引的名称
path = F:\coreseek-3.2.14-win32/var/data/test
#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
docinfo = extern
mlock = 0
morphology = none
#最小分词大小
min_word_len = 1
#是否过滤html标签
html_strip = 0
#中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/
#charset_dictpath = /usr/local/mmseg3/etc/ #BSD、Linux环境下设置,/符号结尾
charset_dictpath = F:\coreseek-3.2.14-win32/etc/
#Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/...
charset_type = zh_cn.utf-8}
---------------------------------------------------------------------------------------------------------------------------------------------------
a表sql示例:
CREATE TABLE `a` (
`counter_id` int(11) NOT NULL,
`max_id` int(11) DEFAULT NULL,
PRIMARY KEY (`counter_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
---------------------------------------------------------------------------------------------------------------------------------------------------
php范例代码:
'.$v1.'
require './sphinxapi.php';
// 实列化
$s= new SphinxClient();
// 连接服务
$s->setServer('127.0.0.1',9312);
//链接模式
//SPH_MATCH_ANY 匹配查询词中的任意一个.redis,匹配r,e,d,i,s任何一个
//SPH_MATCH_ALL 匹配所有查询词(默认模式) 匹配redis
//$s->setMatchMode(SPH_MATCH_BOOLEAN);
if(empty($_GET['keyword'])){
$keyword = '';die();
}else{$keyword = $_GET['keyword'];}
$res = $s->query($keyword);
//$res = $s->query("$keyword !memcached & !memcache");
if(empty($res["matches"])){
echo '没有查询到对应数据!';die();
}
$ids = '';
foreach ($res['matches'] as $k => $v) {
$ids .= ','.$k;
}
$ids = trim($ids,',');
$mysqli = new mysqli('127.0.0.1','root','root','test');
$sql = "select * from test where id in($ids)";
$obj = $mysqli->query($sql);
$data = [];
while ( $row = $obj->fetch_row() ) {
$row = $s->buildExcerpts($row,'test',$keyword,array(
'before_match' => "",
"after_match" => ''
));
$data[] = $row;
}
foreach ($data as $key => $value) {
foreach ($value as $k1 => $v1) {
echo '
}
}