【发布时间】: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 个连接,它也不会因为我表现不佳而跳出来。