在运行其中包含布尔全文搜索的查询时,我遇到了间歇性的 oom 错误。
我在 AWS Aurora (t2.medium) 上。
这是一个示例查询,考虑到表“sets”在列(savename、title)上有一个全文索引,并且其中有大约 200 万行。
select sets.id, sets.title,
drafts.draftId as draftId,
folderSets.folderId as folderId,
concat_ws(' ', savedBy.firstname, savedBy.lastname) as savedBy,
match(sets.savename, sets.title) against ("+s*" in boolean mode) as relevance
from sets as sets
join folderSets as folderSets on folderSets.setId = sets.id
join folders as folders on folders.id = folderSets.folderId
left join draftSets as drafts on drafts.originalId = sets.id and drafts.userId = ?
left join users as savedBy on savedBy.id = folderSets.userId
where (folders.userId = ?)
and match(sets.savename, sets.title) against ("+s*" in boolean mode)
order by relevance
limit 0, 25;
此查询大约需要 5 秒才能运行。如果我敲了几次,查询很可能会失败并出现 OOM。
如果我将布尔全文搜索短语从“+s*”更改为“+sam*”——因此通配符之前有更多字符——相同的查询在大约 0.15 秒内执行,没有任何问题。
如果我从查询中删除布尔搜索 altogehter,查询运行得更快,没有任何问题。
因此,查询的布尔全文部分似乎发生了一些事情,达到了 mysql 限制。
以下是 innodb 全文系统变量:
ft_boolean_syntax................... + -><()~*:""&|
ft_max_word_len..................... 84
ft_min_word_len..................... 1
ft_query_expansion_limit............ 20
ft_stopword_file.................... /dev/null
innodb_ft_aux_table.................
innodb_ft_cache_size................ 8000000
innodb_ft_enable_diag_print......... OFF
innodb_ft_enable_stopword........... OFF
innodb_ft_max_token_size............ 84
innodb_ft_min_token_size............ 1
innodb_ft_num_word_optimize......... 2000
innodb_ft_result_cache_limit........ 2000000000
innodb_ft_server_stopword_table.....
innodb_ft_sort_pll_degree........... 2
innodb_ft_total_cache_size.......... 640000000
innodb_ft_user_stopword_table.......
有没有人对可以进行任何调整以减少与布尔全文相关的 OOM 的可能性有任何建议?我不清楚这是可以/应该在 sql 查询级别/mysql innodb 设置级别/或者如果我处于需要增加 aws rds 实例大小的情况。
在此先感谢您的帮助!
阅读手册可以找到该
innodb_ft_result_cache_limit
变量的描述:此变量的默认值在您的情况下有效,这意味着每次运行查询时,它都会尝试分配最多 2 GB(在“G”的老式意义上)来存储“中间和最终文本搜索的结果”。这是 MySQL 分配的所有其他内存池的补充。
order by relevance limit 0, 25
在您的查询中可能意味着必须在内存中检索和排序匹配查询搜索条件的整个结果集,然后才能返回 25 行。为了避免 OOM 条件,您可以
innodb_ft_result_cache_limit
针对您的用例减少一个更合理的值(如果您的文本搜索条件太宽,这可能会导致错误),或者扩大您的服务器以适应您的需求。听起来您可能需要 500M x 5 个进程并且内存不足。
您的选择:
innodb_buffer_pool_size
以释放一些 RAMinnodb_ft_result_cache_limit
——然后处理可能导致查询失败的结果。同时,
folderSets
闻起来像多:多映射表