1

我有一个查询连接 4 个表中的数据以提供基于测试结果的数据。该查询工作正常,除了它为每行唯一数据返回两条相同的记录。如果我在连接中的一个表的主键列 (a.id) 前面抛出一个 DISTINCT,则可以消除所有重复项。但是,我已经阅读(并发现)DISTINCT 往往会导致性能下降,因此我希望尽可能找到性能更好的解决方案。希望我只是在用很容易修复的 JOINS 做一些愚蠢的事情。这是在 postgresql-9.0.x 上,是的,我知道如果我升级到 9.1.x,那么我可能会做一个“按 a.id 分组”,但现在我被困在 9.0.x 上。

这是查询:

SELECT a.id,a.suiteid,a.testname
     ,date_trunc('second',a.last_update) AS last_update
     ,regexp_replace(p.relname,E'tests','','g')
     ,o.osname 
FROM smoketests AS a
   , pg_class AS p
   , smoke AS t
   , osversmap AS o 
WHERE a.osversion=o.osversion
  AND a.suiteid=t.id
  AND a.tableoid=p.oid
  AND ( a.current_status='FAILED' )
  AND ( a.arch='i386' )
  AND ( a.os='Darwin' )
  AND a.last_update>'2012-05-01 04:00:00'
  AND a.last_update<'2012-05-02 14:20:45' 
ORDER BY a.id ;

产生这个输出:

    id    | suiteid |     testname     |     last_update     | regexp_replace |   osname   
----------+---------+------------------+---------------------+----------------+------------
 32549818 |  668232 | bug377064        | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x
 32549818 |  668232 | bug377064        | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x
 32549819 |  668232 | funcmem_resize   | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x
 32549819 |  668232 | funcmem_resize   | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x
 32549820 |  668232 | leitest          | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x
 32549820 |  668232 | leitest          | 2012-05-01 08:38:07 | smoke          | OSX-10.7.x

该问题在 id 列中可见,其中每个值返回两个,即使 a.id 是烟表的唯一主键并且实际上没有重复项。'smoke' 表与smoketests 表有一对多的关系,但我仍然很困惑为什么我会得到所有内容的副本。

4

1 回答 1

3

您应该做的第一件事是停止执行隐式交叉连接。这些使得追踪这类问题变得更加困难。将您的查询重写为:

SELECT a.id,a.suiteid,a.testname
     ,date_trunc('second',a.last_update) AS last_update
     ,regexp_replace(p.relname,E'tests','','g')
     ,o.osname 
FROM smoketests AS a
JOIN pg_class AS p ON a.tableoid=p.oid
JOIN smoke AS t ON a.suiteid=t.id
JOIN osversmap AS o ON a.osversion=o.osversion
WHERE
  AND ( a.current_status='FAILED' )
  AND ( a.arch='i386' )
  AND ( a.os='Darwin' )
  AND a.last_update>'2012-05-01 04:00:00'
  AND a.last_update<'2012-05-02 14:20:45' 
ORDER BY a.id ;

从那里您需要找出导致重复的原因。烟雾会导致重复吗?尝试返回更多记录。如果是这样,请尝试删除连接并将其替换为 IN 子查询。

于 2013-04-01T10:03:04.547 回答