多个连接以获取不同值的相同查找列

时间:2013-07-31 14:05:11

标签: sql sybase sybase-iq

我们有一个相当大的SQL查询,性能相当差。其中一个问题(来自分析查询计划)是我们拥有的连接数。

基本上我们在数据中有值,我们需要在另一个表上查找。获取要显示给用户的值。问题是我们在同一个表上进行了4次连接,因为有4个不同的列都需要相同的查找。

希望这张图可能会更清晰

Raw_Event_data
event_id,   datetime_id,         lookup_1, lookup_2, lookup_3, lookup_4
1,          2013-01-01_12:00,    1,        5,        3,         9          
2,          2013-01-01_12:00,    121,      5,        8,         19
3,          2013-01-01_12:00,    11,       2,        3,         32
4,          2013-01-01_12:00,    15,       2,        1,         0

Lookup_table
lookup_id,      lookup_desc
1,              desc1
2,              desc2
3,              desc3
...

我们的查询看起来像这样

Select 
    raw.event_id, 
    raw.datetime_id,
    lookup1.lookup_desc,
    lookup2.lookup_desc,
    lookup3.lookup_desc,
    lookup4.lookup_desc,
FROM 
    Raw_Event_data raw, Lookup_table lookup1,Lookup_table lookup2,Lookup_table lookup3,Lookup_table lookup4
WHERE raw.event_id = 1 AND
raw.lookup_1 *= lookup1 AND
raw.lookup_2 *= lookup2.lookup_id AND
raw.lookup_3 *= lookup3.lookup_id AND
raw.lookup_4 *= lookup4.lookup_id

所以我得到了输出

 1, 2013-01-01_12:00, desc1, desc5, desc3, desc9

正如我所说的查询有效,但联接正在扼杀性能。 这是我给出的一个简单的例子,实际上会有12个连接,如上所述,我们不会选择特定事件,而是选择一系列事件。

问题是,有没有更好的方法来进行这些连接。

2 个答案:

答案 0 :(得分:0)

相关的子查询可能是要走的路:

   SELECT r.event_id
        , r.datetime_id
        , (select lookup1.lookup_desc from lookup_table lookup1 where lookup1.lookup_id = r.lookup_1) as desc_1
        , (select lookup2.lookup_desc from lookup_table lookup2 where lookup2.lookup_id = r.lookup_2) as desc_2
        , (select lookup3.lookup_desc from lookup_table lookup3 where lookup3.lookup_id = r.lookup_3) as desc_3
        , (select lookup4.lookup_desc from lookup_table lookup4 where lookup4.lookup_id = r.lookup_4) as desc_4
     FROM Raw_Event_data r
    WHERE r.event_id = 1
        ;

答案 1 :(得分:0)

我的第一次尝试是自己处理索引,如果我被DBA拒绝了。

declare @start_range bigint, @end_range bigint

select
    @start_range = 5
    ,@end_range = 500

create local temporary table raw_event_subset
( --going to assume some schema based on your comments...obviously you will change these to whatever the base schema is.
    event_id bigint
    ,datetime_id timestamp
    ,lookup_1 smallint
    ,lookup_2 smallint
    --etc
) on commit preserve rows

create HG index HG_temp_raw_event_subset_event_id on raw_event_subset (event_id)
create LF index LF_temp_raw_event_subset_lookup_1 on raw_event_subset (lookup_1)
create LF index LF_temp_raw_event_subset_lookup_2 on raw_event_subset (lookup_2)
--etc

insert into raw_event_subset
select
    event_id
    ,datetime_id
    ,lookup_1
    ,lookup_2
    --,etc
from raw_event_data
where event_id >= @start_range --event_id *must* have an HG index on it for this to be worthwhile.
and event_id <= @end_range

--then run your normal query, except replace raw_event_data with raw_event_subset
select
    event_id
    ,datetime_id
    ,l1.lookup_desc
    ,l2.lookup_desc
    --etc
from raw_event_subset r
left join lookup_table l1
    on l1.lookup_id = r.lookup_1
left join lookup_table l2
    on l2.lookup_id = r.lookup_2
    --etc

drop table raw_event_subset

希望这会有所帮助...