一.对原SQL语句的分析
  1.查询语句的where条件,有大量@var in…or(@var=”)的片段
  2.where条件有like‘%’+@var+’%’
  3.where条件有case…end函数
  4.多次连接同一表查询,另外使用本身已嵌套的视图表,是不是必须,是否可替代?
  5.SQL语句有*号,视图中也有*号出现
  二.优化设计
  首先是用存储过程改写,好处是设计灵活。
  核心思想是:用一个或多个查询条件(查询条件要求至少输入一个)得到临时表,每个查询条件如果查到集合,更新这张临时表,后汇总的时候,只需判断这个临时表是否有值。以此类推,可以建立多个临时表,将查询条件汇总。

  这样做目前来看至少两点好处:
  1.省去了对变量进行=@var or(@var=”)的判断;
  2.抛弃sql拼接,提高代码可读性。
  再有是在书写存储过程,这个过程中要注意:
  1.尽量想办法使用临时表扫描替代全表扫描;
  2.抛弃in和not in语句,使用exists和not exists替代;
  3.和客户确认,模糊查询是否有必要,如没有必要,去掉like语句;
  4.注意建立适当的,符合场景的索引;
  5.踩死“*”号;
  6.避免在where条件中对字段进行函数操作;
  7.对实时性要求不高的报表,允许脏读(with(nolock))。
  三.存储过程
  如果想参考优化设计片段的详细内容,请参阅SQL代码:
  /**
  *某某跟踪报表
  **/
  --exec spName1'','','','','','','公司代号'
  CREATE Procedure spName1
  @MESOrderID nvarchar(320),--工单号,多30个
  @LotName nvarchar(700),--产品序列号,多50个
  @DateCode nvarchar(500),--供应商批次号,多30个
  @BatchID nvarchar(700),--组装件序列号/物料批号,多50个
  @comdef nvarchar(700),--组装件物料编码,多30个
  @SNCust nvarchar(1600),--外部序列号,多50个
  @OnPlant nvarchar(20)--平台
  AS
  BEGIN
  SET NOCOUNT ON;
  /**
  *1)定义全局的临时表,先根据六个查询条件的任意一个,得出临时表结果
  **/
  CREATE TABLE#FinalLotName
  (
  LotName NVARCHAR(50),--序列号
  SourceLotName NVARCHAR(50),--来源序列号
  SNCust NVARCHAR(128)--外部序列号
  )
  --1.1
  IF@LotName<>''
  BEGIN
  SELECT Val INTO#WorkLot FROM fn_String_To_Table(@LotName,',',1)
  SELECT LotPK,LotName INTO#WorkLotPK FROM MMLots WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkLot b WHERE b.Val=MMLots.LotID)
  --求SourceLotPK只能在这里求
  SELECT a.LotPK,a.SourceLotPK into#WorkSourcePK FROM MMLotOperations a WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkLotPK b WHERE b.LotPK=a.LotPK)AND a.SourceLotPK IS NOT NULL
  SELECT a.LotPK,a.SourceLotPK,b.LotName INTO#WorkSourcePK2 FROM#WorkSourcePK a JOIN#WorkLotPK b ON a.LotPK=b.LotPK
  INSERT INTO#FinalLotName SELECT a.LotName,b.LotName AS SourceLotName,NULL FROM#WorkSourcePK2 a JOIN(SELECT LotPK,LotName FROM MMLots WITH(NOLOCK))b on a.SourceLotPK=b.LotPK--b的里面加不加WHERE RowDeleted=0待确定
  SELECT a.LotName,a.SourceLotName,b.SNCust INTO#FinalLotNameX1 FROM#FinalLotName a LEFT JOIN CO_SN_LINK_CUSTOMER b WITH(NOLOCK)ON a.LotName=b.SNMes
  DELETE FROM#FinalLotName
  INSERT INTO#FinalLotName SELECT LotName,SourceLotName,SNCust FROM#FinalLotNameX1
  END
  --1.2
  IF@BatchID<>''
  BEGIN
  SELECT Val INTO#WorkSourceLot FROM fn_String_To_Table(@BatchID,',',1)
  IF EXISTS(SELECT 1 FROM#FinalLotName)--如果@LotName也不为空
  BEGIN
  SELECT a.LotName,a.SourceLotName,a.SNCust INTO#FinalLotNameX2 FROM#FinalLotName a WHERE EXISTS(SELECT 1 FROM#WorkSourceLot b WHERE a.SourceLotName=b.Val)
  DELETE FROM#FinalLotName
  INSERT INTO#FinalLotName SELECT LotName,SourceLotName,SNCust FROM#FinalLotNameX2
  END
  ELSE--@LotName条件为空
  BEGIN
  SELECT LotPK AS SourceLotPK,LotName AS SourceLotName INTO#2 FROM MMLots WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkSourceLot b WHERE b.Val=MMLots.LotID)
  SELECT a.LotPK,a.SourceLotPK into#21 FROM MMLotOperations a WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#2 b WHERE b.SourceLotPK=a.SourceLotPK)
  SELECT a.LotPK,a.SourceLotPK,b.SourceLotName INTO#22 FROM#21 a JOIN#2 b ON a.SourceLotPK=b.SourceLotPK
  INSERT INTO#FinalLotName SELECT b.LotName,a.SourceLotName,NULL FROM#22 a JOIN(SELECT LotPK,LotName FROM MMLots WITH(NOLOCK))b on a.LotPK=b.LotPK--b的里面加不加WHERE RowDeleted=0待确定
  SELECT a.LotName,a.SourceLotName,b.SNCust INTO#FinalLotNameX21 FROM#FinalLotName a LEFT JOIN CO_SN_LINK_CUSTOMER b WITH(NOLOCK)ON a.LotName=b.SNMes
  DELETE FROM#FinalLotName
  INSERT INTO#FinalLotName SELECT LotName,SourceLotName,SNCust FROM#FinalLotNameX21
  END
  END
  --1.3
  IF@SNCust<>''
  BEGIN
  SELECT Val INTO#WorkCustomSN FROM fn_String_To_Table(@SNCust,',',1)
  IF EXISTS(SELECT 1 FROM#FinalLotName)--前面两个条件至少有一个有值
  BEGIN
  SELECT a.LotName,a.SourceLotName,a.SNCust INTO#FinalLotNameX3 FROM#FinalLotName a WHERE EXISTS(SELECT 1 FROM#WorkCustomSN b WHERE a.SNCust=b.Val)
  DELETE FROM#FinalLotName
  INSERT INTO#FinalLotName SELECT LotName,SourceLotName,SNCust FROM#FinalLotNameX3
  END
  ELSE
  BEGIN
  SELECT a.SNMes INTO#WorkLotX FROM CO_SN_LINK_CUSTOMER a WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkCustomSN b WHERE a.SNCust=b.Val)
  -------------------以下逻辑和变量1(@LotName)类似[先根据外部序列号求解序列号,再照搬第一个判断变量的方式]
  SELECT LotPK,LotName INTO#WorkLotPKX FROM MMLots WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkLotX b WHERE b.SNMes=MMLots.LotID)
  --求SourceLotPK只能在这里求
  SELECT a.LotPK,a.SourceLotPK into#WorkSourcePKX FROM MMLotOperations a WITH(NOLOCK)WHERE EXISTS(SELECT 1 FROM#WorkLotPKX b WHERE b.LotPK=a.LotPK)AND a.SourceLotPK IS NOT NULL
  SELECT a.LotPK,a.SourceLotPK,b.LotName INTO#WorkSourcePK2X FROM#WorkSourcePKX a JOIN#WorkLotPKX b ON a.LotPK=b.LotPK
  INSERT INTO#FinalLotName SELECT a.LotName,b.LotName AS SourceLotName,NULL FROM#WorkSourcePK2X a JOIN(SELECT LotPK,LotName FROM MMLots WITH(NOLOCK))b on a.SourceLotPK=b.LotPK--b的里面加不加WHERE RowDeleted=0待确定
  SELECT a.LotName,a.SourceLotName,b.SNCust INTO#FinalLotNameX31 FROM#FinalLotName a LEFT JOIN CO_SN_LINK_CUSTOMER b WITH(NOLOCK)ON a.LotName=b.SNMes
  DELETE FROM#FinalLotName
  INSERT INTO#FinalLotName SELECT LotName,SourceLotName,SNCust FROM#FinalLotNameX31
  -----------------------
  END
  END
  /**
  *2)定义全局的临时表,用于替换第一个全局临时表。
  **/
  CREATE TABLE#FinalCO_SN
  (
  SN NVARCHAR(50),
  SourceSN NVARCHAR(50),
  SNCust NVARCHAR(128),
  matl_def_id NVARCHAR(50),--sn的物料ID
  ComMaterials NVARCHAR(50),--SourceSN的物料ID
  MESOrderID NVARCHAR(20),
  OnPlantID NVARCHAR(20),
  VendorID NVARCHAR(20),
  DateCode NVARCHAR(20),
  SNNote NVARCHAR(512)
  )
  --2.1
  IF@MESOrderID<>''
  BEGIN
  -------------------------------将MESOrderID做特殊处理-----------------------------------
  SELECT Val INTO#WorkMESOrderID FROM fn_String_To_Table(@MESOrderID,',',1)
  IF@OnPlant='Comba'
  BEGIN
  UPDATE#WorkMESOrderID SET Val='C000'+Val WHERE LEN(Val)=9
  END
  ELSE
  BEGIN
  UPDATE#WorkMESOrderID SET Val='W000'+Val WHERE LEN(Val)=9
  END
  SELECT SN,MaterialID,MESOrderID,OnPlantID INTO#WorkCO_SN1 FROM CO_SN_GENERATION a WITH(NOLOCK)
  WHERE SNType='IntSN'AND SNRuleName='ProductSNRule'AND OnPlantID=@OnPlant
  AND EXISTS(SELECT 1 FROM#WorkMESOrderID b WHERE a.MESOrderID=b.Val)
  ------------------------------------------------------------------------------------------