我正在处理一个表的性能问题,似乎我无法找到解决此问题的好方法。我创建了到期索引,但我们有数百万行,查询仍然很慢。
该表表示在令牌中拆分的文本以及每个令牌的其他信息。我知道有些人可能认为这可以使用全文搜索引擎完成,但我们不能。请相信我。
表模式如下:
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
是外部密钥Position
是一个索引位置,用于指定文件WordForm
是令牌本身PoS
是单词form Lemma
是单词形式行示例:
1, 1, 'The', 'ART', 'The'
1, 2, 'table', 'NOUN', 'table'
1, 3, 'is', 'VER', 'be'
...
有问题的查询如下:
在上下文中找到所有“rivolgimento”的单词形式,即 被前一个和后面的 10 字包围
注意:10可以是另一个数字,上下文单词也是逗号,点等。
结果的一个例子是:
cuor trasparente,mi par bene di conchiuder con affettuoso rivolgimento alla dissimulazione stessa。 Ovirtù,che sei il
我现在所做的是检索每个匹配行的所有IdFile
和Position
数字,然后循环它们以检索前一个和后面的N个单词。正如您所理解的,这意味着1 + N个查询,对于大N,它会导致响应非常慢。
主要问题还在于人们也可以使用列上的REGEX进行搜索,这会使查询速度变慢。
我想使用GROUP_CONCAT,但不确切知道如何。
答案 0 :(得分:1)
你会得到10个字的方式" rivolgimento":
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;
答案 1 :(得分:0)
根据Gordon Linoff提供的提示,我提出了这个问题:
select ltr.*, group_concat(lt.WordForm separator ' ')
from midia_lemmatized_text ltr join
midia_lemmatized_text lt
on ltr.`WordForm` = 'rivolgimento' and
lt.position between ltr.position - 10 and ltr.position + 10 and
lt.IdFile = ltr.IdFile
group by ltr.IdFile, ltr.position;