查询优化,我还能做些什么?

时间:2017-02-15 11:10:56

标签: mysql performance query-optimization

Table type: MyISAM
Rows: 120k
Data Length: 30MB
Index Length: 40MB

my.ini,MySQL 5.6.2 Windows

read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 16M

Windows Server 2012,12GB RAM,SSD 400MB / s

1慢查询:

SELECT article_id, title, author, content, pdate, MATCH(author, title, content) 
AGAINST('Search Keyword') AS score FROM articles ORDER BY score DESC LIMIT 10;

执行此查询需要352ms使用索引。分析后,它表明大部分时间都花在创建排序索引上。 (完整细节:http://pastebin.com/raw/jT58DCN5

2更快的查询:

SELECT article_id, title, author, content, pdate, MATCH(author, title, content) 
AGAINST('Search Keyword') AS score FROM articles LIMIT 10;

执行此查询需要23ms并进行全表扫描,我不喜欢全表扫描。

问题/问题是,查询#1是我需要使用的,因为排序非常重要。

我有什么办法可以加快查询/重写并获得相同的结果(#1)?

感谢任何输入和帮助。

2 个答案:

答案 0 :(得分:0)

也许你只是期待太多?做一个

的350毫秒
  • MATCH(author, title, content) AGAINST('Search Keyword')
  • ORDER BY
在120k的唱片上,对我来说听起来不是太糟糕;特别是如果content是“非常大”的话。 ......

请记住,对于您的" SLOW QUERY"要工作,系统必须读取每个行,计算得分,然后最后对所有得分进行排序,找出最低的10个值,然后返回所有相关的行信息。如果您遗漏ORDER BY,那么它只需选择 前10行 行,只需计算这10行的score

那就是说,我认为EXPLAIN有点误导,因为它似乎归咎于SORT上的所有内容,而最有可能是大部分时间占用的MATCH。我猜测MATCH()运算符是在“懒惰”中执行的。方式,因此仅在询问数据时才运行,在这种情况下,正在进行排序。

要弄清楚这一点,只需添加一个新列score并将查询拆分为两部分。

  • UPDATE articles SET score = MATCH()等... =>我估计需要大约300毫秒
  • SELECT article_id, title, author, content, pdate, score FROM articles ORDER BY score DESC LIMIT 10; =>我估计需要大约50毫秒

当然这不是一个有效的解决方案,但是如果我说得对,它会告诉你问题不在于SORT,而在于全文搜索......

PS:你忘了提及表上的索引,也可能有用。 cf https://dev.mysql.com/doc/refman/5.7/en/innodb-fulltext-index.html

答案 1 :(得分:0)

尝试以下变体:

AGAINST('word')
AGAINST('+word')
AGAINST('+word' IN BOOLEAN MODE)

尝试

SELECT ... MATCH ...,
    FROM tbl
    WHERE  MATCH ...  -- repeat the test here
    ...

测试是消除根本不匹配的行,从而大大减少要排序的行数。 (同样,取决于+BOOLEAN。)

(我通常使用全部三个:+BOOLEANWHERE MATCH。)

key_buffer_size = 2G也可能会有所帮助。

你应该考虑转移到FT更快的InnoDB。