五千年(敝帚自珍)

主题:【探讨】论坛搜索功能的优化。 -- 铁手

共:💬15
全看树展主题 · 分页首页 上页
/ 1
下页 末页
家园 【探讨】论坛搜索功能的优化。

目前论坛的搜速做的相对简单,甚至是有些简陋,但是消耗资源相对的就要比平常的多了很多。

具体的做法是这样的SQL语句

select (标题内容等) from A TABLE where 标题字段 like '%search key words%'

其中的%是任意字符。比如要搜索任何含有“西西河”字样的标题,可以用'%西西河%'来实现。

问题是在于,这样的 where 条件不能使用任何INDEX。对关键词的搜索,就需要对每一条记录进行相关内容的匹配。目前西西河大概有30万个贴左右,每一个搜速,就需要查30万条记录。这个资源消耗就有些大了。

不知道各位有没有觉得这个方法可以进行一些优化?

另外,不知道是否有人用过这个 www.mnogosearch.org 网站索引工具?支持不支持中文?

家园 LIKE 操作符的优化:

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语句是即时解释还是如存储过程一样的编译执行?

等等等等吧。

家园 是 mysql 数据库。接下去会用 php+mysql

数据库正式版本还没有中文全文检索功能,新的5。0会有,但是不知道效果如何,目前也暂时不能用。除非是自己的专用服务器,自己来折腾

目前实用的版本也还没有存储过程。但是5。0里有。

如果可能的话,各位也可以比较一下MYSQL和PostgreSQL。可能的话,也可以考虑转到PostgreSQL。

家园 俺的经验,postgres不比mysql快
家园 我看到的一些说法是MYSQL一旦达到相当数量的记录,就会慢

大概是快到百万条的时候吧。

PostgreSQL我能看到的好处是它的存储过程。速度是会慢一些,而且用户群也相对比较小。看过一些两者比较的文章,还是很有吸引力,只是从来没用过,没感性认识。

家园 这个也是不错的主意,我回头看一下那个文章
家园 老大得找个搜索专业的来

以俺个人的短见,SQL对于全文搜索是无能为力的,LIKE会有巨大的浪费--数据库的SQL介面都可以显示统计数据,试一下就可以。%×%的结果是所有页都会hit,而全文搜索必须要%x%。

必须找个索引,这方面俺不懂。有一点想法,恐怕也不大行,不过说说也无妨,见笑。

许多网站是google index的。google的搜索可以限定使用网站--西西河是否用过这个功能俺不大清楚,因为俺没用过西西的搜索功能。这样做的缺点是时滞,还没有索引的不能搜索。

不知道有没有服务上提供索引的。

家园 mysql是许多dotcom的数据库

现在许多华尔街的大银行也在使用,数据量很大,似乎也能顶住。当然硬件配置恐怕是小公司难于比较的。

postgres似乎很少在华尔街听到过--也许是俺孤陋寡闻。

家园 mnogosearch 是个OPENSOURCE的搜索引擎

可以用来站内的全文索引,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,结果呢,程序性能有了很大提高。

点看全图

外链图片需谨慎,可能会被源头改

点看全图

外链图片需谨慎,可能会被源头改

点看全图

外链图片需谨慎,可能会被源头改

外链出处

家园 俺觉得无论如何优化,全文搜索SQL都不灵,需索引

俺不是本专业,如有俺说错了,请高人指正。

如果要快,可以使用modphp(俺用过modperl,比perl CGI快很多)。modphp会有一些限制(比php)。

家园 LIKE只有一种用法

就是上面的兄弟说的 LIKE "xxxx%",这个是可以使用索引的。除此之外,建议忘掉LIKE,如果使用LIKE "%xxx"这样,任何胆敢把匹配符号放在开头的做法,结果通常是不妙的,因为这种情况下索引根本不起作用。

车东有一篇文章谈到了全文搜索,是个基于Java的什么玩意,名字我忘了。车东本人这篇文章写得也不错,还探讨了一下中文分词技术,建议Google一下这篇文章来看看,相信会有启发。这个Java的东西好象确实不错,在MySQL手册的用户意见(见FullText Search一节)中,有人强力推荐过。

全看树展主题 · 分页首页 上页
/ 1
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河