Mic*_*ael 6 mysql full-text-search
我昨天在dba.stackexchange.com上问了这个问题,但没有得到任何答复,所以我在这里尝试一下。
我的数据库中的某些查询出现 MySQL 1032“无法在‘person’中找到记录”错误,并且无法解决它们。
这是表格:
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`first_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`dob` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `person_full_idx` (`last_name`,`first_name`,`title`)
) ENGINE=InnoDB AUTO_INCREMENT=4448 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Run Code Online (Sandbox Code Playgroud)
失败的查询是
SELECT * FROM person p0_
WHERE MATCH (p0_.last_name , p0_.first_name , p0_.title) AGAINST ('anne' IN BOOLEAN MODE) > 0.5
ORDER BY p0_.last_name ASC, p0_.first_name ASC, p0_.dob ASC;
Run Code Online (Sandbox Code Playgroud)
如果我取出任何一个 order by 子句,查询就会正常运行。如果我将 anne 更改为 anna,则查询对于所有三个 order by 子句都运行得很好。桌子上有一些安妮,大约和安娜的数量一样多。
每次查询失败时,MySQL 错误日志都会有一堆这样的错误消息:
2019-03-27T17:31:27.891405Z 9 [Warning] [MY-012853] [InnoDB] Using a
partial-field key prefix in search, index `FTS_DOC_ID_INDEX` of table
`database`.`person`. Last data field length 8 bytes, key ptr now
exceeds key end by 4 bytes. Key value in the MySQL format:
len 4; hex 05110000; asc ;
Run Code Online (Sandbox Code Playgroud)
我没有使用复制,并且对于 anne 记录来说插入、更新和删除都是成功的。我删除并重新创建了全文索引,但没有任何改进。我删除并重新加载数据库并得到相同的错误。
使用相同的数据,查询在生产环境(mysql Ver 15.1 Distrib 10.1.37-MariaDB)中不会失败。据我所知,它只在我的开发机器上失败(mysql Ver 8.0.15 for osx10.14 on x86_64 (Homebrew))。
接下来我应该尝试什么?
正如上面评论中指出的,这是 MySQL 8.0 中的一个已知错误:https://bugs.mysql.com/bug.php ?id=93241
临时解决方法是增加sort_buffer_size. MySQL 8.0 中默认的sort_buffer 大小为 256KB,您可以配置的最大值为 2^32-1 或 2^64-1。
如果您运行的查询匹配大量行,以至于对于您增加的sort_buffer_size.
我警告不要增加sort_buffer_size太大,因为运行此查询的每个线程都会分配自己的排序缓冲区。
假设将 sort_buffer_size 增加到 1GB,然后 100 个并发客户端同时运行全文搜索!您可能会意外地使 MySQL 超出您的系统总内存,并且当发生这种情况时您不会收到任何警告。