我正在处理的表存在性能问题,并且似乎无法找到解决此问题的良好解决方案。我创建了应有的索引,但我们有数百万行,查询仍然很慢。
该表表示按标记拆分的文本以及每个标记的其他信息。我知道你们中的一些人可能认为这可以使用全文搜索引擎来完成,但我们不能。请相信我。
表架构如下:
CREATE TABLE `midia_lemmatized_text`
(
`IdFile` CHAR(15) NOT NULL,
`Position` INTEGER NOT NULL,
`WordForm` VARCHAR(48) NOT NULL,
`Pos` VARCHAR(16) NOT NULL,
`Lemma` VARCHAR(64) NOT NULL,
PRIMARY KEY (`IdFile`,`Position`),
INDEX `midia_lemmatized_text_FI_2` (`Pos`),
INDEX `midia_lemmatized_text_FI_3` (`WordForm`),
CONSTRAINT `midia_lemmatized_text_FK_1`
FOREIGN KEY (`IdFile`)
REFERENCES `midia_metadata` (`Id`),
CONSTRAINT `midia_lemmatized_text_FK_2`
FOREIGN KEY (`Pos`)
REFERENCES `midia_pos` (`Pos`)
) ENGINE=InnoDB CHARACTER SET='utf8';
哪里
IdFile
是外部 keyPosition
是一个索引位置,指定当前标记在文件中的位置WordForm
是 token 本身PoS
是单词形式的词性引理
是单词形式的引理
行示例:
1, 1, 'The', 'ART', 'The'
1, 2, 'table', 'NOUN', 'table'
1, 3, 'is', 'VER', 'be'
...
查询
有问题的查询如下所示:
Find all the word forms that are "rivolgimento" in context, that is surrounded by the previous and following 10 words
注意:10 可以是另一个数字,上下文单词也可以是逗号、点等。
结果示例如下:
cuor trasparente , mi par bene di conchiuder con affettuoso rivolgimento alla dissimulazione stessa . O virtù , che sei il
我现在要做的是检索每个匹配行的所有 IdFile
和 Position
编号,然后循环遍历它们以检索前一个和后一个 N 个单词。正如您所理解的,这意味着 1 + N 个查询,对于较大的 N,它会导致响应非常慢。
主要问题还在于人们还可以在列上使用 REGEX 进行搜索,这会使查询速度更加缓慢。
我想使用GROUP_CONCAT但不知 Prop 体如何。
最佳答案
围绕“rivolgimento”获得 10 个单词的方式:
select lt.*
from lemmatized_text ltr join
lemmatized_text lt
on ltr.lemma = 'rivolgimento' and
lt.position between ltr.position - 10 and ltr.position + 10;
如果您希望每次出现“rivolgimento”时将单词排成一行,则类似于:
select ltr.position, group_concat(lt.lemma separator ' ')
from lemmatized_text ltr join
lemmatized_text lt
on ltr.lemma = 'rivolgimento' and
lt.position between ltr.position - 10 and ltr.position + 10
group by ltr.position;
关于mysql - 如何将这 N 个查询变成 1 个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18589451/