我有两个很大的table,环境是 ms sql 2008
现从两个表中列出几个列  where a.id=b.id
但是发现速度很慢,2000行资料大概需要5分钟。请问,改用 inner join效率会高点么?它们是否后台的操作是否完全一样?
还是需要其他的方法提高性能?谢谢了

解决方案 »

  1.   

    yes, agree above opinion
      

  2.   

    inner join 的效果和where a.id=b.id一个样的。慢的话还是要看执行计划,看百分比在哪里
      

  3.   

    这个问题应该不难,建议你提供如下东西
    1,把完整的T-SQL语句贴出来。
    2,把T-SQL中关联到的所有表的schema(表的定义)贴出来。
      

  4.   


    select wo.ProductName,w.WorkOrder, MIN(w.MoveInTime) as MIN_MoveInTime, MAX(w.moveouttime) as MAX_MoveOutTime, 
    CAST(DATEDIFF(HOUR, MIN(w.MoveInTime), MAX(w.moveouttime)) * 1.0/24 as DECIMAL(6,4)) as CycleTime
    from WaferHistory w WITH(NOLOCK), WorkOrder wo WITH(NOLOCK)
    where 
    wo.completedate >= '2013-1-1'
    and wo.completedate <= '2013-3-1'
    and wo.WorkOrderType='11'
    and wo.WorkOrderID = w.WorkOrder
    group by w.WorkOrder,wo.ProductName
    order by w.WorkOrder,wo.ProductName ;显示估计的计划:
    这张表有14g,奇怪的是发现没有建立 聚集索引,不知道和这个有没有关系?
      

  5.   

    WorkOrder 列上已经有索引了,不过没有用到,可能是book lookup的成本太大了,因为你的语句里还引用的WH表里的其他列。另外,
    1. 你的1.1号到3.1号的数据占整个WH表里数据的百分比是多少?
    2. WorkOrder的数据唯一性如何,是不是大多是重复数据?可以尝试把WorkOrder,moveintime,moveouttime做个联合索引,这样可以形成索引覆盖,看看能不能把表扫描给消除掉
      

  6.   


    问题1:不到5%
    问题2:实际workorder数据是唯一的。
      

  7.   

    1,首先你要确保 WorkOrderID 为WorkOrder的聚集索引,如果没有,马上建。2,既然WorkOrder为唯一的,把对就WaferHistory 的WorkOrder建的聚集索引。
    用如下语句,
    ALTER TABLE [dbo].[WaferHistory] ADD  CONSTRAINT [PK_WaferHistory] PRIMARY KEY CLUSTERED 
    (
    [WorkOrder] ASC
    )3,然后建如下INDEX脚本,
    /****** Object:  Index [NonClusteredIndex-20130322-114418]    Script Date: 3/22/2013 12:09:55 PM ******/
    CREATE NONCLUSTERED INDEX [NonClusteredIndex-20130322-1144181] ON [dbo].[WorkOrder]
    (
    [completedate] ASC,
    [WorkOrderType] ASC,
    [ProductName] ASC
    )
      

  8.   


    那应该就是book lookup的成本太大了,考虑试试复合索引:WorkOrder,moveintime,moveouttime
    聚集索引也不是必须要建,但如果建你这里可能会比较慢,因为其他非聚集索引也要刷新一次。
    还可以考虑下数据归档,你都14G了,如果可行,把历史数据清一清。
      

  9.   


    如果真的想要建聚集索引的话,在生产环境可以加上 with online = on,以保证用户访问的正常