从单个表中检索具有不同值的同一列的多个输出时的性能问题

Posted

技术标签:

【中文标题】从单个表中检索具有不同值的同一列的多个输出时的性能问题【英文标题】:Performance issue in retrieving multiple output of the same column with different values from a single table 【发布时间】:2012-11-08 00:16:37 【问题描述】:

是否可以从查询中获得以下结果而不加入同一个表三次(或)而不读取相同的“wordlocation”表三次(或者如果有更多单词则更多)?如果有三个或更多的单词,大约需要一分钟多的时间才能返回结果。

目前“wordlocation”表有三行分别是(“bookid”、“wordid”、“location”),目前有917802行。

我想做的是

    检索包含“wordid”查询中指定的所有单词的“bookid”。 每本书中所有单词(来自查询)的总字数 每个单词位置的最小值,例如(min(w0.location), min(w1.location)

我尝试注释掉 count(w0.wordid) 和 min(location) 计算,看看它们是否影响性能,但事实并非如此。多次加入同一个表就是这种情况。

(与上图代码相同)

select 
    w0.bookid, 
    count(w0.wordid) as wcount, 
    abs(min(w0.location) + min(w1.location) + min(w2.location)) as wordlocation, 
    (abs(min(w0.location) - min(w1.location)) + abs(min(w1.location) - min(w2.location))) as distance 
    from 
    wordlocation as w0 
    inner join 
    wordlocation as w1 on w0.bookid = w1.bookid 
    join 
    wordlocation as w2 on w1.bookid = w2.bookid 
    where 
    w0.wordid =3 
    and 
    w1.wordid =52 
    and 
    w2.wordid =42
    group by w0.bookid 
    order by wcount desc;

这是我正在寻找的结果,也是我通过运行上述查询获得的结果,但如果我指定超过 3 个单词,则需要很长时间,例如(w0 = 3, w1 = 52, w2 = 42, w3 = 71)

【问题讨论】:

【参考方案1】:

试试这个查询

    SELECT bookid,
      ABS(L3+L52+L42) as wordlocation,
      ABS(L3-L52)+ABS(L52-L42) as distance
    FROM 
      (SELECT bookid, wordid, CASE WHEN wordid=3 THEN min(location) ELSE 0 END L3,
         CASE WHEN wordid=52 THEN min(location) ELSE 0 END L52,
         CASE WHEN wordid=42 THEN min(location) ELSE 0 END L42
      FROM wordlocation WL
      WHERE wordid in (3,52,42)
      GROUP BY bookid, wordid) T
    GROUP BY bookid

您可能还需要在wordid上创建索引

【讨论】:

谢谢。我会试试。 wordid 已编入索引。 @thaky 请告诉我是否有帮助。

以上是关于从单个表中检索具有不同值的同一列的多个输出时的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

如何从两个表中选择同一字段中具有相同值的行?

具有单个键的多个值的STL集合

MySQL Select ID 出现在具有多个特定值的列的不同行上

Java 中 MySQL 插入语句的性能:批处理模式准备语句与具有多个值的单个插入

将一些数据从 sqlite 表复制到具有不同两列的同一个表中

合并来自谷歌表格列的记录