【问题标题】:Multiple joins to get the same lookup column for different values多个连接以获得不同值的相同查找列
【发布时间】:2013-08-01 02:41:53
【问题描述】:

我们有一个相当大的 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 个像上面这样的连接,我们不会选择特定事件,而是选择一系列事件。

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

【问题讨论】:

  • 从未使用过 Sybase,但在 Oracle 中,我会考虑首先将事件范围放入 temporary table,然后才使用 lookup_table 进行连接。这可能是您的解决方案吗?
  • 是的,这是我们系统其他部分使用的一个选项,我们可能会在这里做类似的事情。我的问题更多的是,有没有办法解决这些表上的多个连接,而不是寻求一种方法来使用其他技巧来改进查询,如果你理解我的话
  • 也许创建一个join index?检查这个link
  • 我知道您希望我们只编写一个更有效的查询,而不会陷入其他细节,我愿意,但我认为首先介绍 Sybase IQ 基础知识很重要。我不建议使用“加入”索引,因为它在较新版本的 IQ 上已被弃用。原始事件表的所有“lookup_n”列上是否都有“HG”或“LF”索引? lookup_id 是不是lookup_table 的主键,如果不是,它上面至少有一个HG 索引吗? IQ 在存储空间方面非常有效,如果它们没有被索引,我想不出你不应该添加它们的充分理由。
  • 并澄清我询问索引的原因......当正确索引时,IQ 在执行这样的连接方面非常有效,特别是如果那些“lookup_n”列的基数相对较低。即使有 12 个连接,它也不会因为我表现不佳而跳出来。

标签: sql sybase sap-iq


【解决方案1】:

如果我被 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

希望这会有所帮助...

【讨论】:

    【解决方案2】:

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

       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
            ;
    

    【讨论】:

    • 是的,看起来可能。我会尝试一下,看看它是如何工作的。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 2011-09-18
    • 2022-10-14
    • 1970-01-01
    相关资源
    最近更新 更多