SQL查询优化

时间:2013-07-01 20:52:25

标签: sql database postgresql-9.1

有人可以帮我优化我的SQL查询。这个数据库是postgres。我的表结构如下:

create table test_table(test_id integer NOT NULL, sequence_id integer NOT NULL,value1 integer NOT NULL, value2 integer NOT NULL, CONSTRAINT test_table_pk PRIMARY KEY (test_id , sequence_id ))

create table test_event(event_id integer NOT NULL,test_id integer NOT NULL, sequence_id integer NOT NULL , CONSTRAINT test_event_pk PRIMARY KEY(event_id , test_id, sequence_id))

test_table
1,1, 200,300
2,2, 400,500
2,3, 600,700
2,4, 300,500
2,5, 200,900

test_event
1, 1,1
1, 2,2
1, 2,3
2, 2,4
2, 2,5

我想从test_table获取所有value1和value2,其中sequence_id和test_id对应于test_event中的event_id = 1。 我的查询看起来像

SELECT
  value1, value2
FROM
  test_table
WHERE
  sequence_id IN (
    SELECT sequence_id
    FROM test_event
    WHERE event_id=1) AND
  test_id IN (
    SELECT test_id
    FROM test_event
    WHERE event_id=1)

有人可以告诉我这是否是编写此查询的最佳方式?

2 个答案:

答案 0 :(得分:3)

您可以使用INNER JOIN来优化查询,这样您就不必在两次不同的属性中查询'test_event'表。

SELECT t.value1, t.value2
FROM test_table t, test_event e 
WHERE e.event_id = 1 
    AND t.test_id = e.test_id 
    AND t.sequence_id = e.sequence_id

编辑:添加了评论中提供的建议。

SELECT t.value1, t.value2  
FROM test_table t INNER JOIN test_event e  
ON ( e.event_id = 1  
    AND t.test_id = e.test_id 
    AND t.sequence_id = e.sequence_id)

答案 1 :(得分:1)

问题是sequence_idtest_id是否必须来自test_event中的相同记录。例如,对(1,2)满足原始查询,因为偶数id 1序列id 2都在event_id = 1的行上,但它们不在同一行上。

您的in查询可能是表达此关系的最佳方式。另一种方法是使用join和聚合:

SELECT tt.value1, tt.value2
FROM test_table tt join
     test_event te
     on te.event_id = 1
group by tt.value1, tt.value2
having sum(case when tt.sequence_id = te.sequence_id then 1 else 0 end) > 0 and
       sum(case when tt.event_id = t2.event_id then 1 else 0 end) > 0;

这会将in替换为join(基本上是交叉联接)和aggregation。我猜想,对于te.sequence_idte.event_id上的索引,您的原始版本会更好。