hic*_*123 11 mysql innodb full-text-search
我目前正在尝试针对 Stack Overflow 评论的数据转储运行一些查询。这是架构的样子:
CREATE TABLE `socomments` (
`Id` int(11) NOT NULL,
`PostId` int(11) NOT NULL,
`Score` int(11) DEFAULT NULL,
`Text` varchar(600) NOT NULL,
`CreationDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`UserId` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `idx_socomments_PostId` (`PostId`),
KEY `CreationDate` (`CreationDate`),
FULLTEXT KEY `Text` (`Text`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
我对表运行了这个查询,它运行得非常慢(它确实有 2900 万行,但它有一个全文索引):
SELECT *
FROM socomments
WHERE MATCH (Text) AGAINST ('"fixed the post"' IN BOOLEAN MODE)
Run Code Online (Sandbox Code Playgroud)
所以我分析了它,结果是:
|| Status || Duration ||
|| starting || 0.000058 ||
|| checking permissions || 0.000006 ||
|| Opening tables || 0.000014 ||
|| init || 0.000019 ||
|| System lock || 0.000006 ||
|| optimizing || 0.000007 ||
|| statistics || 0.000013 ||
|| preparing || 0.000005 ||
|| FULLTEXT initialization || 207.1112 ||
|| executing || 0.000009 ||
|| Sending data || 0.000856 ||
|| end || 0.000004 ||
|| query end || 0.000004 ||
|| closing tables || 0.000006 ||
|| freeing items || 0.000059 ||
|| logging slow query || 0.000037 ||
|| cleaning up || 0.000046 ||
Run Code Online (Sandbox Code Playgroud)
如您所见,它在 FULLTEXT 初始化中花费了很长时间。这是正常的吗?如果没有,我该如何解决?
小智 6
如果您使用 InnoDB FULLTEXT 索引,如果您正在查询具有大量已删除行的表,则查询通常会挂在“FULLTEXT 初始化”状态。在 InnoDB 的 FULLTEXT 实现中,在对受影响的表运行后续 OPTIMIZE 操作之前,不会修剪已删除的行。参见:https : //dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html
要删除已删除记录的全文索引条目,您必须在索引表上使用 innodb_optimize_fulltext_only=ON 运行 OPTIMIZE TABLE 以重建全文索引。
还可以通过查询information_schema.innodb_ft_deleted 来检查已删除但未清除的记录数
要解决此问题,应定期对具有 InnoDB FULLTEXT 索引的表运行 OPTIMIZE TABLE。
其他人发现这是一个麻烦的情况
全文初始化
服务器正准备执行自然语言全文搜索。
你唯一的办法就是用更少的数据做准备。如何 ?
再看看你的查询。它正在选择所有列。我会重构查询以仅从socomments
. 然后,将那些检索到的 id 加入到socomments
表中。
SELECT B.* FROM
(SELECT id FROM socomments
WHERE MATCH (Text) AGAINST ('"fixed the post"' IN BOOLEAN MODE)) A
LEFT JOIN socomments B USING (id);
Run Code Online (Sandbox Code Playgroud)
这可能会产生一个更丑陋的 EXPLAIN 计划,但我认为分析会变得更好。基本思想是:如果你有一个激进的全文搜索,让它在那个FULLTEXT initialization
阶段收集最少的数据,从而减少时间。
我之前已经推荐过很多次了
May 14, 2012
:全文和左连接的慢查询Mar 18, 2012
:为什么在 MySQL 中的 FULLTEXT 索引上 LIKE 比 MATCH...AGAINST 快 4 倍多?Jan 26, 2012
:Mysql全文搜索my.cnf优化:Oct 25, 2011
: FULLTEXT 索引在 BOOLEAN MODE 中被忽略,“字数”有条件请确保您设置的是基于 InnoDB 的 FULLTEXT 选项,而不是 MyISAM 的选项。您应该关注的两个选项是
想一想。文本字段是 VARCHAR(600)。假设平均值是 300 字节。你有 29,000,000 百万个。那将是一点点 8GB。也许增加innodb_ft_cache_size和innodb_ft_total_cache_size也可能有所帮助。
确保您有足够的 RAM 用于更大的 InnoDB FULLTEXT 缓冲区。
归档时间: |
|
查看次数: |
12443 次 |
最近记录: |