我现在有一个需求,有表T1,T2,T1是前端信息表,记录的是监测系统所有有效前端的信息,包括这个前端的ID,编号,IP,类型等等,T2是这些前端发生报警的信息表,包括报警的各类信息如报警的ID,开始时间,结束时间,类型,T1和T2都有字段F1即ID,我现在要统计各前端不同报警,我写的SQL语句如下:
SELECT T1.l_ParentRegionID as l_ParentRegionCode, T1.l_SubRegionCode as l_SubRegionCode, 
T2.l_StopType as l_StopType, T2.l_Dealwith as l_Dealwith , COUNT(T1.l_ParentRegionID) 
AS l_Count, MAX(T2.l_StopBeginTime) AS l_StopBeginTime 
FROM T1 LEFT OUTER JOIN 
T2 ON T1.l_ParentRegionID = T2.l_ParentRegionCode AND 
T1.l_SubRegionCode = T2.l_SubRegionCode 
GROUP BY T1.l_ParentRegionID, T2.l_Dealwith, T2.l_StopType, 
T1.l_SubRegionCode 
HAVING (T2.l_Dealwith IS NULL) AND (MAX(T2.l_StopBeginTime) 
IS NULL) OR 
(T2.l_Dealwith = 0) AND (MAX(T2.l_StopBeginTime) <> 0) 
ORDER BY T1.l_ParentRegionID, T1.l_SubRegionCode, 
MAX(T2.l_StopBeginTime) DESC
表T2有几个索引在l_PlayStopID即报警ID,l_ParentRegionCode,以及报警通道号,开始,结束时间,
现在表T1中大概有100条数据,即表示有100个前端
表T2中大概有30W条数据,即表示有30W个报警信息,
用我上面的联合查询,最少也要6秒才能完成,各位大牛帮想想我该怎么修改SQL或是表设计
另外服务器用的是HP Proliant G5 380

解决方案 »

  1.   

    用了这么多MAX,慢是肯定的,要不我帮你转到SQL区,这是什么数据库。
      

  2.   

    T1.l_ParentRegionID , T2.l_ParentRegionCode ,T1.l_SubRegionCode, T2.l_SubRegionCode
    这些链接字段都有索引么?没有的话加上 
      

  3.   

    聚合函数用到的字段加索引  max  count  ;
    order by 后的字段加索引;HAVING (T2.l_Dealwith IS NULL) AND (MAX(T2.l_StopBeginTime) 
    IS NULL) OR 
    (T2.l_Dealwith = 0) 可以直接写在where里,最后那个可以用having。
      

  4.   

    ---使用索引优化数据库查询效率
    1.不宜创建索引的情形
    (1)经常插入,修改和删除的表
    (2)数据量比较小的表,因为查询优化器在搜索索引时所花费的时间可能会大于遍历全表的数据所需要的时间2.适合创建索引的情形
    (1)为where子句中出现的列创建索引
    (2)创建组合索引
    (3)为group by 子句中出现的列创建索引3.聚集索引的设计原则
    (1)该列的数值是唯一的或者很少有重复的记录
    (2)经常使用between ...and..按顺序查询的列
    (3)定义identity的唯一列.
    (4)经常用于对数据进行排序的列.---无法使用索引的select语句
    1.对索引列使用了函数,如:
    select * from tb where max(id)=1002.对索引列使用了'%xx',如:
    select * from tb where id like '%1'
    需要注意的不是所有使用like关键字的select 语句都无法使用索引,比如
    select * from tb where id like '1%'就可以使用索引3.在where子句中对列进行类型转换(其实也是使用到了函数)4.在组合索引的第1列不是使用最多的列,如在下面3个查询语句中建立组合索引,按顺序包含col2,col1,id列;
    select * from tb where id='1' and col1='aa'
    select id,sum(col1) from tb group by id
    select * from tb where id='2' and col2='bb'
    则第一句和第二句无法使用到索引 所以需要注意组合索引的顺序5.在where 子句中使用in关键字的某些句子
    当在in关键字后面使用嵌套的select语句,将无法使用在该列上定义的索引
    如:
    select 
     *
    from
     ta 
    where
     id 
    in
     (select id from tb where ....)--这样可以用到索引
    select * from tb where id in('1','2')
      

  5.   

    l_StopBeginTime 字段加 索引
      

  6.   

    首先感觉感谢你的建议
    其次:你的意思是Having里AND左右的(T2.l_Dealwith IS NULL) 和 (MAX(T2.l_StopBeginTime) 放进where条件里,然后只是having (T2.l_Dealwith = 0) ?
      

  7.   

    LZ试试SELECT T1.l_ParentRegionID as l_ParentRegionCode, T1.l_SubRegionCode as l_SubRegionCode, 
    T2.l_StopType as l_StopType, T2.l_Dealwith as l_Dealwith , COUNT(T1.l_ParentRegionID) 
    AS l_Count, MAX(T2.l_StopBeginTime) AS l_StopBeginTime 
    FROM T1 LEFT OUTER JOIN 
    T2 ON T1.l_ParentRegionID = T2.l_ParentRegionCode AND 
    T1.l_SubRegionCode = T2.l_SubRegionCode 
    where (T2.l_Dealwith IS NULL) or (T2.l_Dealwith = 0)
    GROUP BY T1.l_ParentRegionID, T2.l_Dealwith, T2.l_StopType, 
    T1.l_SubRegionCode 
    HAVING (MAX(T2.l_StopBeginTime)IS NULL) OR (MAX(T2.l_StopBeginTime) <> 0) 
    ORDER BY T1.l_ParentRegionID, T1.l_SubRegionCode, 
    MAX(T2.l_StopBeginTime) DESC
      

  8.   

    下面有关的字段
    ON T1.l_ParentRegionID = T2.l_ParentRegionCode AND 
    T1.l_SubRegionCode = T2.l_SubRegionCode 
    GROUP BY T1.l_ParentRegionID, T2.l_Dealwith, T2.l_StopType, 
    T1.l_SubRegionCode