2017-08-05 63 views
0

我有一个大表(large_table,6M +行)与索引列Sybase ASE的:优化与多个子查询

  • 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的” IDS,并行运行(使用应用程序中的线程池,有固定数量的工人):这导致没有改进,加上100%的数据库CPU。
  • 更换与“在从large_table(选择ID large_table.id”“存在(来自large_table吨选择1其中t.id = large_table.id”:这也造成成无改善

任何想法?

+1

*从不*在'FROM'子句中使用逗号。 *总是*使用正确的,明确的'JOIN'语法。 –

+0

你可以分享查询计划吗? – Meherzad

回答

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 ...

+0

不使用内部连接语法的效果是什么? – Sybuser

+0

查询的效率应该没有差别。这只是一个语法选择。但是,在“where”条款中加入条件是如此......八十年代呢?这是关于它的[博客](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx)。 – trincot