Sybase ASE:使用多个子查询优化查询

时间:2017-08-05 08:54:15

标签: sql performance indexing sybase sybase-ase

我有一个带有索引列的大表(large_table,6M +行)

  • id主键
  • small_ref_id(整数)引用小表的主键(small_table,2k +行)
  • mid_ref_id(整数)引用中型表的主键(mid_table,200k +行)

  • small_table的数据除以索引列group_name(varchar)中指定的数据组。

  • mid_table的数据除以索引列类型(varchar)中指定的数据类型。

  • 大表有2个索引时间戳(date_time1,date_time2)。

  • 媒体表有1个索引时间戳(date_time3)。

我的查询如下:

select * from large_table, mid_table, small_table 
where large_table.small_ref_id=small_table.id
and large_table.mid_ref_id=mid_table.id
and small_table.group_name='MyGroup'
and 
   (large_table.id in (select large_table.id from large_table, mid_table
where mid_table.id=large_table.mid_ref_id 
and large_table.date_time1 between '2010-01-01' and '2017-01-01' 
and mid_table.type='Type1')
or large_table.id in (select large_table.id from large_table, mid_table 
where mid_table.id=large_table.mid_ref_id 
and large_table.date_time2 between '2010-06-01' and '2017-01-01' 
and mid_table.type='Type2')
or large_table.id in (select large_table.id from large_table, mid_table 
where mid_table.id=large_table.mid_ref_id 
and mid_table.date_time3 between '2010-08-01' and '2017-01-01' 
and mid_table.type='Type3'))

获取结果可能需要几分钟(<5分钟)。

我尝试了什么:

  • 通过small_ref_id将查询拆分为与'MyGroup'内的ID一样多的查询,并行运行(使用应用程序内部的线程池,具有固定数量的工作人员):这导致没有任何改进,加上100%的数据库CPU。
  • 将“large_table”中的“large_table.id”替换为“exists(从big_table t中选择1,其中t.id = large_table.id”):这也没有任何改进。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

在我看来,你不需要子查询。您只需将这三个条件应用于主查询中已有的large_tablemid_table数据:

select     * 
from       large_table 
inner join mid_table
        on large_table.mid_ref_id = mid_table.id
inner join small_table 
        on large_table.small_ref_id = small_table.id
       and small_table.group_name = 'MyGroup'
where      (
                (large_table.date_time1 between '2010-01-01' and '2017-01-01' 
                 and mid_table.type = 'Type1')
            or
                (large_table.date_time2 between '2010-06-01' and '2017-01-01' 
                 and mid_table.type = 'Type2')
            or  
                (mid_table.date_time3 between '2010-08-01' and '2017-01-01' 
                 and mid_table.type = 'Type3')
           )

作为旁注:使用inner join syntax

注意:你确定最后的情况吗?它在mid_table.date_time3上进行测试,而其他两个条件则从large_table ...

开始