2

我有这三个表:

  1. 创建表词(id 整数、词文本、频率整数);
  2. 创建表格句子(id整数,句子文本);
  3. 创建表索引(wordId 整数、sentenceId 整数、位置整数);

索引是倒排索引,表示哪个单词出现在哪个句子中。此外,我有一个来自表格单词和句子的 id 索引。

此查询确定给定单词出现在哪些句子中并返回第一个匹配项:

select S.sentence from sentences S, words W, index I
where W.word = '#erhoehungen' and W.id = I.wordId and S.id = I.sentenceId
limit 1;

但是当我想检索两个单词一起出现的句子时,例如:

select S.sentence from sentences S, words W, index I
where W.word = '#dreikampf' and I.wordId = W.id and S.id = I.sentenceId and
S.id in (
    select S.id from sentences S, words W, index I
    where W.word = 'bruederle' and W.id = I.wordId and S.id = I.sentenceId
)
limit 1;

这个查询要慢得多。有什么技巧可以加快速度吗?以下是我到目前为止所做的事情:

  • 将 shared_buffer 增加到 32MB
  • 将 work_mem 增加到 15MB
  • 在所有表上运行分析
  • 如前所述,在单词 id 和句子 id 上创建索引

问候。

€编辑:

这是解释分析查询语句的输出:http: //pastebin.com/t2M5w4na

这三个 create 语句实际上是我原来的 create 语句。我应该在表格句子和单词中添加主键并将它们作为索引中的外键引用吗?但是我应该为索引表使用什么主键?SentId 和 wordId 一起不是唯一的,即使我添加 pos 表示单词在句子中的位置,它也不是唯一的。

更新为:

  1. 创建表词(id整数、词文本、频率整数、主键(id));
  2. 创建表格句子(id整数,句子文本,主键(id));
  3. 创建表索引(wordId整数,sentenceId整数,位置整数,外键(wordId)引用单词(id),外键(sentenceId)引用句子(sentenceId));
4

2 回答 2

1

我想这应该更有效:

SELECT s.id, s.sentence FROM words w
JOIN INDEX i ON w.id = i.wordId
JOIN sentences s ON i.sentenceId = s.id
WHERE w.word IN ('#dreikampf', 'bruederle')
GROUP BY s.id, s.sentence
HAVING COUNT(*) >= 2

只需确保IN子句中的项目数量与子句中的项目数量相匹配HAVING

在这里拉小提琴。

于 2013-10-27T22:41:44.090 回答
0

看起来您在 columns 上没有索引wordIdsentenceId. 请创建它们,查询将更快地工作。

CREATE INDEX idx_index_wordId ON index USING btree (wordId);
CREATE INDEX idx_index_sentenceId ON index USING btree (sentenceId);

使用保留字index作为表名不是一个好主意——在某些情况下您可能需要对其进行转义。可能您还应该idindex表中添加列并使其成为主键。

请使用Mosty Mostacho查询并explain analyze在创建索引后显示它的输出。也许它可以工作得更快。

更新:

请尝试新查询:

select S.sentence from sentences S where S.id in
(select sentenceId from index I where 
I.wordId in (select id from words where word IN ('#dreikampf', 'bruederle'))
group by I.sentenceId
having count(distinct I.wordId) = 2
limit 1)
于 2013-10-28T02:15:47.560 回答