0

我正在处理的表存在性能问题,似乎我无法找到解决此问题的好方法。我创建了到期索引,但我们有数百万行,查询仍然很慢。

该表表示拆分为令牌的文本以及每个令牌的其他信息。我知道你们中的一些人可能认为这可以使用全文搜索引擎完成,但我们不能。请相信我。

表架构如下:

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是词形的词性
  • 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 。O virtù , che sei il

我现在要做的是检索每个匹配行的所有IdFilePosition数字,然后遍历它们以检索前面和后面的 N 个单词。正如您所理解的,这意味着 1 + N 个查询,对于较大的 N,它会导致响应非常慢。

主要问题还在于人们还可以在列上使用 REGEX 进行搜索,这会使查询更加缓慢。

我想使用GROUP_CONCAT但不知道具体如何。

4

2 回答 2

1

你会在“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;
于 2013-09-03T10:52:41.953 回答
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;
于 2013-09-03T12:33:36.833 回答