查询优化,我还能做啥?
Posted
技术标签:
【中文标题】查询优化,我还能做啥?【英文标题】:Query Optimization, What more can I do?查询优化,我还能做什么? 【发布时间】:2017-02-15 11:10:56 【问题描述】: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;
执行此查询需要 352 毫秒使用索引。 profiling 后,显示大部分时间都花在了创建排序索引上。 (完整详情: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)?
感谢任何意见和帮助。
【问题讨论】:
【参考方案1】:也许您只是期望过高? 350ms 做一个
MATCH(author, title, content) AGAINST('Search Keyword')
订购人
对我来说,120k 唱片听起来并不太寒酸;特别是如果content
是“大”...
请记住,要使您的“慢查询”起作用,系统必须读取每一行,计算分数,然后最后对所有分数进行排序,找出最低的 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:您忘记提及表上的索引是什么,知道也可能有用。 cfhttps://dev.mysql.com/doc/refman/5.7/en/innodb-fulltext-index.html
【讨论】:
嗯,内容不大,varchar 255是content字段的最大长度,也就是最大的那个。我有关于作者、标题、内容的所有类型 varchar 的索引,并且符合 FULL TEXT SEARCH 要求。我并不是说我对现在的情况不满意,但该网站正在发展,我只是想确保在投资其他任何东西之前,我已经用这些资源做了可能做的事情。我确实有一些其他选项可能是更有效的优化选项,而不是那个查询。非常感谢任何其他可以提供帮助的意见。【参考方案2】:试试这些变体:
AGAINST('word')
AGAINST('+word')
AGAINST('+word' IN BOOLEAN MODE)
试试
SELECT ... MATCH ...,
FROM tbl
WHERE MATCH ... -- repeat the test here
...
测试是消除根本不匹配的行,从而大大减少要排序的行数。 (同样,取决于+
和BOOLEAN
。)
(我通常使用所有三个:+
、BOOLEAN
和 WHERE MATCH
。)
key_buffer_size = 2G
也可能有帮助。
您应该考虑迁移到 InnoDB,因为 FT 更快。
【讨论】:
以上是关于查询优化,我还能做啥?的主要内容,如果未能解决你的问题,请参考以下文章