下面的语句中,T_ChatLog和T_SalePact的记录都很多,有上百万条,请问该如何优化这个SQL语句?
本意就是求出T_ChatLog表中to_id不在T_SalePact表的buyer_nick中的记录
语句是正确的,就是速度太慢,望大侠指点一二。SELECT     from_id, to_id, MsgDate, ShopId, COUNT(*) AS MsgTotal
FROM         dbo.T_ChatLog AS a
WHERE     MsgType = 1 AND NOT EXISTS(SELECT 1 AS Expr1
                            FROM          dbo.T_SalePact
                            WHERE      (ShopId = a.ShopId) AND (PactSmallDate = a.MsgDate) AND (buyer_nick = a.to_id)))
GROUP BY ShopId, MsgDate, from_id, to_id

解决方案 »

  1.   

    T_ChatLog表和T_SalePact?建了估計快很多
      

  2.   

    ( to_id, MsgDate, ShopId)
    加个索引
      

  3.   

    (ShopId ,PactSmallDate ,buyer_nick )
    也加索引
      

  4.   

    (ShopId = a.ShopId) AND (PactSmallDate = a.MsgDate) AND (buyer_nick = a.to_id)))
    两个表对应都加!  
      

  5.   

    在两表上分别建立复合索引
    T_ChatLog(ShopID,MsgDate,to_id,from_id)
    T_SalePact(ShopID,PactSmallDate,buyer_nick)
      

  6.   

    not exists能用到索引吗?问题是他group by的效率需要提升吧。
      

  7.   

    --除了索引以外,还可以为表T_ChatLog增加一个状态字段ZT,表增加记录时,也要对此字段进行维护
    当ShopId = a.ShopId) AND (PactSmallDate = a.MsgDate) AND (buyer_nick = a.to_id)时,
    此字段可更新为1,即ZT=1查询语句可简化为:
    SELECT from_id, to_id, MsgDate, ShopId, COUNT(*) AS MsgTotal
    FROM dbo.T_ChatLog AS a
    WHERE MsgType = 1 AND ZT<>1
    GROUP BY ShopId, MsgDate, from_id, to_id
      

  8.   

    应该慢在Group上吧, NOT EXISTS没有什么问题,尤其建立了索引后效率不会慢。还是建立索引吧,至于Group By那就只有慢慢来
      

  9.   


    --兩個表都建
    --T_SalePact
    Create index IX_....... on TableName(Col1,Col2,Col3)
    --T_ChatLog
    ....................................................INCLUDE(from_id)
    or
    Create index IX_....... on TableName(Col1,Col2,Col3,from_id)
      

  10.   

    你这里是Group 的问题,如果业务非要这样做。那就没有办法的,除非改变业务。
      

  11.   

    用包含性列 也就是索引覆盖Create index IX_index on TableName(Col1,Col2,Col3) include(....)
      

  12.   

    改成下面看看,增加一个top 可能会提高一些速度
    SELECT from_id, to_id, MsgDate, ShopId, COUNT(*) AS MsgTotal
    FROM dbo.T_ChatLog AS a
    WHERE MsgType = 1 AND NOT EXISTS(SELECT top  1  'a' AS Expr1
      FROM dbo.T_SalePact
      WHERE (ShopId = a.ShopId) AND (PactSmallDate = a.MsgDate) AND (buyer_nick = a.to_id)))
    GROUP BY ShopId, MsgDate, from_id, to_id 
     
     
      

  13.   

    能不能改成用子查询的方法?用子查询的效率是否比group by的效率要高?