主题:【探讨】论坛搜索功能的优化。 -- 铁手
目前论坛的搜速做的相对简单,甚至是有些简陋,但是消耗资源相对的就要比平常的多了很多。
具体的做法是这样的SQL语句
select (标题内容等) from A TABLE where 标题字段 like '%search key words%'
其中的%是任意字符。比如要搜索任何含有“西西河”字样的标题,可以用'%西西河%'来实现。
问题是在于,这样的 where 条件不能使用任何INDEX。对关键词的搜索,就需要对每一条记录进行相关内容的匹配。目前西西河大概有30万个贴左右,每一个搜速,就需要查30万条记录。这个资源消耗就有些大了。
不知道各位有没有觉得这个方法可以进行一些优化?
另外,不知道是否有人用过这个 www.mnogosearch.org 网站索引工具?支持不支持中文?
LIKE操作符
LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%' 这种查询不会引用索引,而LIKE ‘X5400%'则会引用范围索引。一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%' 这个条件会产生全表扫描,如果改成YY_BH LIKE 'X5400%' OR YY_BH LIKE 'B5400%' 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。
所以我建议铁手兄把搜索语句改成
select (标题内容等) from A TABLE where 标题字段 like '西西河%' ,
这样搜索结果只看以西西河起头的文章内容,速度很快,
如果用户想查询 %西西河% ,请在西西河之前手动加上 % 号,这时候再动用比较费劲的 全文检索。
select (标题内容等) from A TABLE where 标题字段 like '%西西河%' ,
尤其是搜索用户名,因为大家对用户名记得比较清楚,完全可以只检索 "landkid%" 这样的字符串,可以大大加快速度。
可怜铁手兄只好自己稍微啃一啃了。
SQL语句优化技术分析
http://blog.blogchina.com/article_62324.1135762.html
比如DBMS是什么?支持哪些特性?有无文本搜索引擎?SQL语句是即时解释还是如存储过程一样的编译执行?
等等等等吧。
数据库正式版本还没有中文全文检索功能,新的5。0会有,但是不知道效果如何,目前也暂时不能用。除非是自己的专用服务器,自己来折腾
目前实用的版本也还没有存储过程。但是5。0里有。
如果可能的话,各位也可以比较一下MYSQL和PostgreSQL。可能的话,也可以考虑转到PostgreSQL。
大概是快到百万条的时候吧。
PostgreSQL我能看到的好处是它的存储过程。速度是会慢一些,而且用户群也相对比较小。看过一些两者比较的文章,还是很有吸引力,只是从来没用过,没感性认识。
以俺个人的短见,SQL对于全文搜索是无能为力的,LIKE会有巨大的浪费--数据库的SQL介面都可以显示统计数据,试一下就可以。%×%的结果是所有页都会hit,而全文搜索必须要%x%。
必须找个索引,这方面俺不懂。有一点想法,恐怕也不大行,不过说说也无妨,见笑。
许多网站是google index的。google的搜索可以限定使用网站--西西河是否用过这个功能俺不大清楚,因为俺没用过西西的搜索功能。这样做的缺点是时滞,还没有索引的不能搜索。
不知道有没有服务上提供索引的。
现在许多华尔街的大银行也在使用,数据量很大,似乎也能顶住。当然硬件配置恐怕是小公司难于比较的。
postgres似乎很少在华尔街听到过--也许是俺孤陋寡闻。
可以用来站内的全文索引,MYSQL自己的网站就是用这个来实现的。只是现在也没时间去钻研那玩意。
俺这方面是白痴,现学是来不及了。
MySQL also uses indexes for LIKE comparisons if the argument to LIKE is a constant string that doesn't start with a wild-card character. For example, the following SELECT statements use indexes:
mysql> select * from tbl_name where key_col LIKE "Patrick%";
mysql> select * from tbl_name where key_col LIKE "Pat%_ck%";
In the first statement, only rows with "Patrick" <= key_col < "Patricl" are considered. In the second statement, only rows with "Pat" <= key_col < "Pau" are considered.
The following SELECT statements will not use indexes:
mysql> select * from tbl_name where key_col LIKE "%Patrick%";
mysql> select * from tbl_name where key_col LIKE other_col;
In the first statement, the LIKE value begins with a wild-card character. In the second statement, the LIKE value is not a constant.
Searching using column_name IS NULL will use indexes if column_name is an index.
MySQL normally uses the index that finds the least number of rows. An index is used for columns that you compare with the following operators: =, >, >=, <, <=, BETWEEN, and a LIKE with a non-wild-card prefix like 'something%'.
Any index that doesn't span all AND levels in the WHERE clause is not used to optimize the query. In other words: To be able to use an index, a prefix of the index must be used in every AND group.
另外,前两天看到一个PHP的新闻。两个捷克的大学生开发了一套PHP的编译器,可以将PHP Code编译成.NET Assembly,结果呢,程序性能有了很大提高。
俺不是本专业,如有俺说错了,请高人指正。
如果要快,可以使用modphp(俺用过modperl,比perl CGI快很多)。modphp会有一些限制(比php)。
就是上面的兄弟说的 LIKE "xxxx%",这个是可以使用索引的。除此之外,建议忘掉LIKE,如果使用LIKE "%xxx"这样,任何胆敢把匹配符号放在开头的做法,结果通常是不妙的,因为这种情况下索引根本不起作用。
车东有一篇文章谈到了全文搜索,是个基于Java的什么玩意,名字我忘了。车东本人这篇文章写得也不错,还探讨了一下中文分词技术,建议Google一下这篇文章来看看,相信会有启发。这个Java的东西好象确实不错,在MySQL手册的用户意见(见FullText Search一节)中,有人强力推荐过。