开发者

How to optimize mysql fulltext union search?

I am making a mysql fulltext search.

my database table article1 has ~18000 articles, article2 has ~7000 articles, article3 has ~13000 articles. FIELD cat is a INDEX field

Now I want to make a union search. there are 5 groups words put into 3 table, match out the results. But the process time is 3.1213495136 seconds. (I add microtime() to see how much time it will cost). Is there any way to optimize mysql fulltext union search? Thanks.

(SELECT title,content,date FROM article1 WHERE 
(cat='novel' AND MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Elizabeth +Bowen' IN BOOLEAN MODE)))
UNION 
(SELECT title,content,date FROM article2 WHERE 
(MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content)AGAINST ('+Elizabeth +Bowen' IN BOOLEAN MODE)))
UNION 
(SELECT title,content,date FROM article3 WHERE 
(MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content)AGAINST ('+Elizabeth +Bowen' 开发者_如何转开发IN BOOLEAN MODE)))
Order By date DESC LIMIT 10


First thing you should do is to add

Order By date DESC LIMIT 10 

into each subquery as you don't need more than 10 results in the end.

There also must be indexes on fields "date" in all tables.

alter table "TABLENAME" add index date_idx(date);

ADDITIONALLY:

You may shorten and slightly speed it query by changing search terms to form: "() | ()"

(SELECT title,content,date FROM article1 WHERE 
(cat='novel' AND MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10)
UNION 
(SELECT title,content,date FROM article2 WHERE 
(MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10)
UNION 
(SELECT title,content,date FROM article3 WHERE 
(MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10)
Order By date DESC LIMIT 10


An alternative to your union would be to carry these out as separate searches. If you order your criteria by relevance, the first set is your best; return partial results and only if there's fewer than 10, try the next match, etc.

Then the query is fast for the end-user, return results in relevance order, and don't waste MySQL resources getting unwanted data. If the user asks for more, a longer, inefficient query can run, but is meaningful then.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜