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.
精彩评论