全文“标题”搜索1M行

时间:2012-02-05 20:43:09

标签: mysql mysql-management

有一个3.3GB articles Myisam表,其中包含以下字段:id, title, perma, body, date 主键:id 全文索引:title

它有1,110,000行。在我这样做之后:

SET GLOBAL key_buffer_size = 2000*1024*1024; LOAD INDEX INTO CACHE articles INDEX(title);

我无法获得足够的表现。

您可以在下面看到几个示例的执行时间:

<9.5381848812103>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<12.734259843826>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('how to play basketball' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('how to play basketball' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<4.4655818939209>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('kill a bird and eat it' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('kill a bird and eat it' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<16.268588066101>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('avoid back pain' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('avoid back pain' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

<12.553371906281>
SELECT SQL_NO_CACHE perma,title,body, MATCH(title) AGAINST('computer' IN BOOLEAN MODE) AS sort
FROM articles  WHERE MATCH(title) AGAINST('computer' IN BOOLEAN MODE) ORDER BY sort DESC LIMIT 30;

有什么建议可以让执行时间更好吗?

2 个答案:

答案 0 :(得分:0)

尝试使用默认的“IN NORMAL MODE”而不是“IN BOOLEAN MODE”。

我不确定您选择“在BOOLEAN模式”中是否有任何特殊原因。我注意到你没有使用“IN BOOLEAN MODE”提供的任何操作符。此外,由于数据集较大,您不必担心50%的阈值。

我建议这样做,因为“IN NORMAL MODE”也会按相关性对结果进行排序,而不需要“ORDER BY”。这是根据MySQL documentation

哦,除非您更改了最小字数,否则“FULLTEXT INDEX”中包含的最短字长为4个字母。因此,除非最小字大小发生变化,否则“反对(...)”中的“for”将是不必要的。

答案 1 :(得分:0)

这是您的第一个查询

SELECT SQL_NO_CACHE perma,title,body,
MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE) AS sort
FROM articles
WHERE MATCH(title) AGAINST('flowers for children' IN BOOLEAN MODE)
ORDER BY sort DESC LIMIT 30;

您可能需要重构此

首先,拿起钥匙和排序值

SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
FROM articles
WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE);

此查询将生成800M临时表

接下来,将其限制为30个最高排序值

SELECT * FROM
(
    SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
    FROM articles
    WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE)
) AA
ORDER BY sort DESC LIMIT 30;

现在确定一个720字节的临时表

最后,LEFT JOIN这30行到articles

SELECT
    B.perma,B.title,B.body,A.sort
FROM
(
    SELECT * FROM
    (
        SELECT id,MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE) sort
        FROM articles
        WHERE MATCH(title) AGAINST ('flowers for children' IN BOOLEAN MODE)
    ) AA
    ORDER BY sort DESC LIMIT 30
) A LEFT JOIN articles B USING (id);

试一试!!!