2010-05-14 133 views
2

我试图克服一个非常严重的性能问题,Sybase拒绝在大型表上使用主键索引,因为其中一个必填字段是通过另一个表间接指定的 - 换句话说,是否可以从Sybase函数返回一个数字列表?

SELECT ... FROM BIGTABLE WHERE KFIELD = 123 

运行于MS但

SELECT ... FROM BIGTABLE, LTLTBL WHERE KFIELD = LTLTBL.LOOKUP 
    AND LTLTBL.UNIQUEID = 'STRINGREPOF123' 

需要30 - 40秒。

我设法通过使用基本上让我这样做的函数来解决这个第一个问题;

SELECT ... FROM BIGTABLE WHERE KFIELD = MYFUNC('STRINGREPOF123') 

它也运行在毫秒。

但问题是,这种方法只适用于有一个由MYFUNCT返回的单个值,但我有一些情况下可能会返回2或3个值。

我知道SQL

SELECT ... FROM BIGTABLE WHERE KFIELD IN (123,456,789) 

也返回以毫秒为单位,所以我想有可能返回值的列表的功能,而不仅仅是一个单一的一个 - 这可能吗?

不幸的是,该应用程序正在Sybase ASA 9上运行。是的,我知道它已旧,并且计划刷新,但现在我无能为力,因此我需要能够与此版本的数据库一起工作的逻辑。

+0

桌子上的标记是什么,showplan显示什么以及这些字段的模式是什么? – Mark 2010-05-14 08:38:52

+0

这有点涉及。首先,BIGTABLE实际上是一种观点,我是Sybase的新手,所以我不知道确切的术语,但它有效地工作,因为分区表跨越几个物理表(实现可能比这更隐含)。底层表的主要索引是KFIELD,DATEVALUE,我实际上将其传递到查询中(查询过于简化)。该showplan表明,它进行全表扫描,而不是使用主键是问题。 – 2010-05-14 17:47:56

+0

还有一个基于DATEVALUE的索引,它实际上是优化器正在选择的内容。这适用于多个分区,因为没有或仅有少量记录被检索到(尽管它仍不如使用主键那样高效,因此我仍然感到困惑)。但是,一旦它到达具有所选时间间隔的大部分记录的表格,它就被迫进行全表扫描。看起来优化器有点试图预取数据表,但我确实没有足够的经验可以肯定地说。 – 2010-05-14 17:55:37

回答

1

如何使用临时表来存储您的号码?所以,你的SQL就像这样:

select kfield into #tmpKfield 
    from littleTable 
    where UNIQUEID = 'STRINGREPOF123' 

    select * from bigTable 
    where kfield in (select kfield from #tmpKfield) 
    go 

    drop table #tmpKfield 
    go 

这就是我如何努力解决您的问题。

相关问题