使用indecies进行SELECT优化

时间:2018-01-14 12:36:52

标签: mysql indexing bigdata where

我目前正在使用关于单词相似度的数据集。数据非常简单 - 您有成对的单词和相似值。 (狗;猫; 43000)

我将原始数据移动到MySQL表格,其中包含以下结构

word1_id: INT(11), Primary Key, Not Null

word2_id: INT(11), Primary Key, Not Null

value: INT(11), Not Null

创建表格时,我还定义了索引(除主键索引外):

PRIMARY: BTREE, #1 word1_id, #2 word2_id

Word2: BTREE, #1 word2_id, #2 word1_id

有50.000个独特的单词。数据是完全静态的 - 一旦你第一次将它导入表中,没有任何变化。 数据的一个示例是:

word1_id ; word2_id ; value

1 ; 2 ; 48971754

1 ; 3 ; 75997417

1 ; 4 ; 18285783

..

1 ; 50000 ; 127

2 ; 3 ; 1046254

2 ; 4 ; 268081

...

目标很简单:对于给定的目标词(int),找到与它最相似的词。

为此,该表必须找到目标INT(例如436)在第1列(436; 543; 475652)或第2列(72; 436; 934454)中的所有条目并返回排序结果,基于第3列。

我的问题如下:

在第一列中查找目标INT时,过程很快(例如0.1秒)。

SELECT
    value, word2_id
FROM
    cooccurrence
    WHERE
        word1_id = (436)
ORDER BY value DESC;

但是,对基于第2列的WHERE语句执行相同的操作需要很长时间(例如1.5 - 10秒)

SELECT
    value, word1_id
FROM
    cooccurrence
    WHERE
        word2_id = (436)
ORDER BY value DESC;

问题:

  1. 为什么基于第2列进行WHERE的速度要慢得多,相反 第1列。索引表不应具有“已排序”版本 基于这两列的数据?

  2. 此表格结构是解决此问题的好方法吗?在那儿 有什么明显的优化吗?

  3. 最终目标是将距离(第3列)设为FLOAT,并且 添加包含Year的第四列(INT)。然后,您将查看多年来与目标最相似的单词列表的变化情况。这意味着数据(和表格)的大小会显着增加 - 例如从几千兆字节到几百千兆字节。这会改变吗? 事情有多大意义?

1 个答案:

答案 0 :(得分:0)

PRIMARY KEY(word1_id, word2_id),
INDEX(word2_id, value, word1_id),
INDEX(word1_id, value, word2_id)

让我剖析

SELECT
    value, word2_id
FROM
    cooccurrence
    WHERE
        word1_id = (436)
ORDER BY value DESC;

使用INDEX(word2_id, value, word1_id)

就是这样的
  1. 找到该索引中最后一次出现的word1_id = (436)。 (WHERE
  2. 向后扫描。 (ORDER BY value DESC
  3. 在每个项目中,投放value, word2_id,(SELECT
  4. 如果您只有大约50K字,请从INT SIGNED更改为MEDIUMINT UNSIGNED。这将节省每行表的6个字节。

    一旦添加了另一列并更改了查询,我所说的内容大多数都不合适。让我们看一下涉及SELECT的{​​{1}}。

    在询问效果查询时,请提供year。这样,我们可以指出它说你得到了什么线索。