如何将这N个查询转换为一个

时间:2013-09-03 10:04:10

标签: mysql sql query-optimization

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

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

表模式如下:

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

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

主要问题还在于人们也可以使用列上的REGEX进行搜索,这会使查询速度变慢。

我想使用GROUP_CONCAT,但不确切知道如何。

2 个答案:

答案 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;