因左连接和多个where子句而导致性能问题

时间:2015-06-06 12:40:24

标签: sql-server performance left-join

这是程序

 create PROCEDURE [dbo].[sample1] (       

     @param1 varchar(20) ,            
     @param2 VARCHAR(5),            
     @param3 varchar(max) = NULL,            
     @param4 varchar(max) = NULL,            
     @param5 varchar(max) = NULL,            
     @param6 bit = 1,       




    @param7 varchar(max) = NULL,            
     @param8 bit = 1,            
     @param9 varchar(max) = NULL,            
     @param10 varchar(max) = NULL,            
     @param11 varchar(max) = NULL,            
     @param12 varchar(5) = 'OP',        
     @param13 varchar(max) = NULL,            
     @TOP int = 101,            
     @SORTFIELD varchar(20) = 'DESCRIPTION',            
     @SORTDIRECTION varchar(5) = 'ASC'            

    )            
    AS            
    BEGIN       


    DECLARE            
     @NOW VARCHAR(10)=(SELECT CONVERT(varchar(10), GETDATE(), 112)),            
     @PHYSNAME VARCHAR(50)='',            

     @PHYPARAMS CHAR(1)='N'            


      /*********************************/         
         SELECT CPPACKAGE_PARAMS, MIN(CODE) AS MinCode, MAX(CODE) AS MaxCode       
         INTO #SNCPPKG_PARAMS_DTLS      
         FROM SNCPPKG_PARAMS_DTLS             
         WHERE CODETYPE = 5      
         GROUP BY CPPACKAGE_PARAMS      

         SELECT *       
         INTO #SNCPPACKAGERL      
         FROM SNCPPACKAGERL       
         WHERE DOMDEF = @param1      

         --SELECT *       
         --INTO #SNCPPROCDEF       
         --FROM SNCPPROCDEF      
         --WHERE DOMDEF = @param1      

         --SELECT *       
         --INTO #SNCPDIAGDEF       
         --FROM SNCPDIAGDEF      
         --WHERE DOMDEF = @param1      
      /*********************************/      
      SELECT           
        @PHYPARAMS=[ParamaterValue]              
       FROM [dbo].[sntbFacilityParamaters] with(nolock)          
       where [ParamaterTypeId] =           
       (SELECT TOP 1 [ParamaterTypeId]          
       FROM [dbo].[sntbParamaterTypeRef] with(nolock)          
       where ParamaterTypeName ='Physician Specific Packages')             
        and facid = @param2          




     IF( ISNULL(@PHYPARAMS  ,'N')='N')            
     BEGIN            
      SET @param11=''            
     END            


     SET NOCOUNT ON;             

      CREATE TABLE #tempGLT1DET (CODEFROM VARCHAR(32))            

          INSERT INTO #tempGLT1DET            
          SELECT A.CODEFROM FROM snlocGLT1DET A with(nolock)           
                INNER JOIN snlocGLTABLE1 B with(nolock) ON A.GLTABLE1 = B.SYSKEY            
          WHERE A.CODETYPE IN ('4', '5')            
                AND NAME = 'AMA HCPCS'             
                AND (B.EFF_DATE <= @NOW OR B.EFF_DATE='')             
                AND (B.TRM_DATE >= @NOW OR B.TRM_DATE='')             
                AND (B.ACTIVATION_DT <= @NOW)            




            if(@top>300)        
            BEGIN        
       SET @top=300        
            END        

            IF(ISNULL(@param5,'')='' )        
            BEGIN        
       SET @param6=0        

            END        

            IF( ISNULL(@param7,'')='')        
            BEGIN        
       SET @param8=0        
            END        

      SELECT * INTO #TEMPPACKAGECOMPLETE              
    FROM                
      (SELECT --TOP(@TOP)          
        A.SYSKEY,              
              A.MCOMMORD,              
              A.SERVTYPE,              
              A.DESCRIPTION,              
              isnull(A.some_ver,'9') as some_ver,                
              A.ER,              
              A.OUTPATIENT,              
              A.INPATIENT,              
              A.DRG,              
              A.EFF_DATE,              
              A.TRM_DATE,              
              A.DOMDEF,              
          A.FINCLASS,              
          A.FORMORD,              
          A.AUDIT,              
          A.ALTDESC,              
          A.CODE,              
         B.TOTALCHARGE,                       
          --null AS  PHYSNAME,          
          A.PHYSNAME,          
          --NULL AS  NPI,          
          A.NPI,              
          A.CPPACKAGE_PARAMS,A.PROCCODE,A.HCPCSRATES      
          --,row_number() over(partition BY A.SYSKEY              
          --                  ORDER BY A.SYSKEY) rn            

    FROM              
     (SELECT *              
      FROM              
        (SELECT  --TOP(@TOP)           
    CPPACKAGEDEF.SYSKEY,              
                         isnull(CPPACKAGEDEF.some_ver,'9') as some_ver,                
                         CPPACKAGEDEF.MCOMMORD,              
                         CPPACKAGEDEF.SERVTYPE,              
                         CPPACKAGEDEF.DESCRIPTION AS 'DESCRIPTION',              
                         CPPACKAGEDEF.ER,              
                         CPPACKAGEDEF.OUTPATIENT,              
                         CPPACKAGEDEF.INPATIENT,              
                         CPPACKAGEDEF.DRG,              
                         CPPACKAGEDEF.EFF_DATE,              
                         CPPACKAGEDEF.TRM_DATE,              
                         CPPACKAGEDEF.DOMDEF,              
                         CPPACKAGEDEF.FINCLASS,           
                         CPPACKAGEDEF.FORMORD,              
                         CPPACKAGEDEF.AUDIT,              
                         CPPACKAGEDEF.ALTDESC,       
                         REVDET.REVCODE,   --REMOVE      
                         P.PROCCODE,REVDET.HCPCSRATES,      
                         CODE = CASE WHEN ISNULL(params.MinCode,'') = '' THEN ''      
                                      WHEN params.MinCode = params.MaxCode THEN params.MinCode                
                                      ELSE 'Multiple' END,      
           --              CODE = CASE WHEN              
           --(SELECT count(1)              
           -- FROM SNCPPKG_PARAMS_DTLS d with(nolock)             
           -- WHERE CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS              
           --   AND CODETYPE = 5) > 1 THEN 'Multiple' ELSE ISNULL(              
           --                                                       (SELECT CODE              
           --                                                        FROM SNCPPKG_PARAMS_DTLS d  with(nolock)             
           --                                                        WHERE CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS              
           --                                                          AND CODETYPE = 5), '') END,              
   CPPACKAGEDEF.CPPACKAGE_PARAMS,              
                                                                                            ISNULL(SC_TYPE,'R')AS SC_TYPE              

         FROM SNCPPACKAGEDEF AS  CPPACKAGEDEF with(nolock)           
         LEFT JOIN #SNCPPKG_PARAMS_DTLS AS params ON params.CPPACKAGE_PARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS      
         LEFT JOIN #SNCPPACKAGERL REVDET   ON REVDET.CPPACKAGEDEF= CPPACKAGEDEF.syskey--           and REVDET.domdef= @param1  
         --start:rajesh:for diag and proc          
         left join SNCPPROCDEF p with (nolock)  on (P.CPPACKAGEDEF = CPPACKAGEDEF.syskey)    and p.domdef= @param1      
   left join SNCPDIAGDEF d with (nolock) on (d.CPPACKAGEDEF = CPPACKAGEDEF.syskey)         and d.domdef= @param1      
       --LEFT JOIN SNCPPACKAGERL pkgRL ON pkgRL.CPPACKAGEDEF= C.syskey           
  where           
   (          
    ((isnull(@param5,'')='') or (d.DIAGCODE like @param5+'%'))          
    and          
    ((isnull(@param7,'')='') or (p.PROCCODE like @param7+'%'))          
    )              
     AND          
    (          
     ((@param13='9') AND (ISNULL(CPPACKAGEDEF.some_ver,'9')='9'))             OR          
((@param13='0') AND (ISNULL(CPPACKAGEDEF.some_ver,'9')='0'))          
     OR          
     (ISNULL(@param13,'')='')           
    )          

   --AND REVDET.          
  -- AND p.DOMDEF = @param1          
   --AND d.DOMDEF = @param1          

   AND          
   (          
  ISNULL(@param7,'')=''        
  OR        
  (          
    (@param12='IP' AND   ISNULL(@param7,'')<>'')        
    --AND          
    --(                  
    --( P.PROCCODE IN            
    --  ( SELECT DISTINCT DESTCODE FROM snVwCodeXWalk XWALK WHERE XWALK.SOURCECODE = @param10)          
    --)                                          
    --)          
  )          

  OR         
  (          
    ((@param12='OP' OR @param12='ER') AND ISNULL(@param7,'')<>'')        
    AND          
    (                
      REVDET.HCPCSRATES like @param10+'%'                      
    )                    
   )        


     )                   


   AND                    

   (          

          (        

           ( (@param5=1  AND @param8=0 )         
    AND           
             (d.SEQUENCE=1)          
           )         
   --or ISNULL(@param5,'')=''         

          )           
          OR            
          (           
           ((@param8=1  AND @param6=0) AND            
            (p.SEQUENCE=1)  )         
            --OR ISNULL(@param7,'')=''        
          )            
          OR          
          (          
           (        
      (@param5=1 )--AND ISNULL(@param5,'')<>'')        
    AND (@param8=1)-- AND ISNULL(@param7,'')<>'')           
    AND (p.SEQUENCE=1 )         
    AND (d.SEQUENCE=1 )        
           )          
          )           
          OR          
          (@param5=0 AND @param8=0)          

   )          
         --end:rajesh for diag and proc          
         --where SYSKEY = '126FAQ00249R' and              
         AND          
          (              
      (CPPACKAGEDEF.DESCRIPTION LIKE '%'+@param3+'%')              
   OR (CPPACKAGEDEF.ALTDESC LIKE '%'+@param3+'%')               
   OR (ISNULL(@param3,'')='')              
    )              

        AND          
      ( (REVDET.REVCODE LIKE @param9+'%') OR (ISNULL(@param9,'')='' ))          
     AND( (CPPACKAGEDEF.DRG LIKE @param4+'%') OR (ISNULL(@param4,'')='') )                   
     AND      
--   ISNULL(CPPACKAGEDEF.SC_TYPE,'R')=              
  --   CASE WHEN @PHYPARAMS='Y'              
    -- THEN 'P'              
     --ELSE              
     --'R'              
 --end       

     (      
          (@PHYPARAMS='Y' AND CPPACKAGEDEF.SC_TYPE='P' AND ISNULL(@param11,'')<>'' )      
          OR      
          (@PHYPARAMS='Y'AND ISNULL(@param11,'')='' )       
          OR       
          (@PHYPARAMS='N'AND ISNULL(CPPACKAGEDEF.SC_TYPE,'R')='R' )       
     )       



      AND (CPPACKAGEDEF.EFF_DATE <= @NOW OR ISNULL(CPPACKAGEDEF.EFF_DATE,'')='')               
            AND (CPPACKAGEDEF.TRM_DATE >= @NOW OR ISNULL(CPPACKAGEDEF.TRM_DATE,'')='')  

       AND CPPACKAGEDEF.DOMDEF=@param1                               
   --AND p.DOMDEF=@param1    
   --AND d.DOMDEF=@param1                   


         ) CPPACKAGEDEF              

      LEFT JOIN              
        (SELECT PHYSNAME,              
                phyPARAMS,              
                NPI              
         FROM              
           (SELECT DISTINCT b.PHYSNAME,              
                            b.NPI,              
                       cp.SYSKEY phyPARAMS,              
                            ROW_NUMBER() OVER (PARTITION BY b.NPI,cp.SYSKEY              
                                               ORDER BY b.MDATE DESC) AS rowNum              
            FROM dbo.BILLPHYS b              
            INNER JOIN SNCPPACKAGE_PARAMS cp with(nolock) ON cp.NPI = b.NPI              
            WHERE ISNULL(b.NPI, '') <> '') phy              
         WHERE phy.rowNum=1) B ON B.phyPARAMS = CPPACKAGEDEF.CPPACKAGE_PARAMS            


      WHERE (CPPACKAGEDEF.SYSKEY <> ''              
             AND CPPACKAGEDEF.AUDIT = 'Z')              
        AND (CPPACKAGEDEF.DOMDEF IN (@param1))              
        AND (          
    ((CPPACKAGEDEF.INPATIENT = 'Y') AND (@param12='IP'))          
    OR          
    ((CPPACKAGEDEF.OUTPATIENT = 'Y') AND (ISNULL(@param12,'OP')='OP'))          
    OR          
    ((@param12='ER' AND CPPACKAGEDEF.OUTPATIENT = 'Y' )AND CONVERT(INT,CPPACKAGEDEF.REVCODE) BETWEEN 450 AND 459)        
  )          


        ) A              
   LEFT JOIN              
     (SELECT SUM(CONVERT(MONEY, LINECHARGE) * UNITS) AS 'TOTALCHARGE', CPPACKAGEDEF  FROM              
           (SELECT LINECHARGE,              
                UNITS,              
                CPPACKAGEDEF              
         FROM #SNCPPACKAGERL with(nolock)) B              
      GROUP BY CPPACKAGEDEF) B ON A.SYSKEY = B.CPPACKAGEDEF                    
      ) A           

     -- LEFT JOIN SNCPPACKAGERL REVDET   ON REVDET.CPPACKAGEDEF= A.syskey AND REVDET.DOMDEF=@param1          

      WHERE               
      --rn= 1              

      --AND      
      ( (A.PHYSNAME LIKE @param11+'%') OR (ISNULL(@param11,'')='' ))          
      --          
         --select * from #TEMPPACKAGECOMPLETE      
      ---             
       --SELECT  count(DISTINCT SYSKEY)FROM #TEMPPACKAGE           
            -- gpant start      
    Select top (@top) * into #TEMPPACKAGE from (Select *,row_number() over(partition BY SYSKEY              
                            ORDER BY SYSKEY) rn  from #TEMPPACKAGECOMPLETE where ((          
  ISNULL(@param7,'')=''        
  OR        
  (          
    (@param12='IP' AND   ISNULL(@param7,'')<>'')        
    AND          
    (                  
    ( PROCCODE IN            
      ( SELECT DISTINCT DESTCODE FROM snVwCodeXWalk XWALK WHERE XWALK.SOURCECODE = @param10)          
    )                                          
    )          
  )          

  OR         
  (          
    ((@param12='OP' OR @param12='ER') AND ISNULL(@param7,'')<>'')        
    --AND          
    --(                
    --  HCPCSRATES like @param10+'%'                      
    --)                    
   )        


     )  ))t where rn =1      

--             --gpant end      
     SELECT               
  --count(distinct T.SYSKEY) AS ScSyskey       
T.SYSKEY AS ScSyskey,            
   T.DESCRIPTION AS ScDescription,              
   T.PHYSNAME AS ScPhysician ,           
   CASE WHEN ISNULL(@param12 ,'OP')='OP' THEN 'OP'          
  ELSE          
     CASE WHEN @param12='IP' THEN 'IP'           
     ELSE          
     CASE WHEN @param12='ER' THEN 'ER'           
   END            
  END          

 END ScPatientType,          
   --'I' AS ScPatientType,              
   T.DRG AS ScDiagnosis,               
    T.CODE AS ScPrimaryCdmProcedure ,              
   CASE WHEN P.DIAG_PRIMARYCODE='Y' THEN  P.DIAGCODE ELSE NULL END  AS ScPrimaryIcdDiagnosis,              
   CASE WHEN P.PROC_PRIMARYCODE='Y' THEN  P.PROCCODE ELSE NULL END  AS ScPrimaryIcdProcedure,               
   ISNULL(T.TOTALCHARGE, 0) AS ScAmount,                         
   T.MCOMMORD AS ScClaimCount,              

   C.CODE AS ScCode,              
   C.CODETYPEDESC AS ScCodeType,              
   T.DESCRIPTION AS ScCodeDescription,              
   CAST(C.DATEFROM AS DATETIME) AS ScDateFrom,              
   CAST(C.DATETO AS DATETIME) As ScDateTo,              

    REVCODE.UNITS AS CdmUnits,              
    REVCODE.UNITSORDAYS AS CdmUnitType,              
    REVCODE.CPT4 AS CdmCode,              
    REVCODE.MODIFIERS AS CdmModifier,              
    REVCODE.REVCODE AS CdmRevenueCode,              
    REVCODE.REVDESC AS CdmDescription,                  
    REVCODE.CHARGECODE AS CdmChargeCode,       
    REVCODE.LINECHARGE AS CdmPerUnitCharge,              

    P.DIAGCODE AS IcdDiagCode,              
    P.DIAG_PRIMARYCODE AS IcdDiagIsPrimary,              
    P.DIAGDESC AS IcdDiagDescription,              
    P.PROCCODE AS IcdProcCode,              
    P.PROC_PRIMARYCODE AS IcdProcIsPrimary,              
    P.PROCDESCS AS IcdProcDescription,        
    p.ProcedureSequence,               
    p.DiagSequence       





    FROM  #TEMPPACKAGE T               
       LEFT JOIN                
            (              
                 select distinct x.syskey as CPPACKAGEDEF,          
     proce.PROCCODE AS PROCCODE,          
     diag.DIAGCODE AS DIAGCODE,          
     PROCDESC.PROCDESC AS PROCDESCS ,          
     DIAGDESC.DIAGDESC AS DIAGDESC,        
     ISNULL(PROCDESC.ICD_CODE_VERSION,'ICD9Proc') as proccode_version ,        
     ISNULL(DIAGDESC.ICD_CODE_VERSION,'ICD9Dx') as diagcode_version,  --ISNULL(p.DIAGDESC.ICD_CODE_VERSION,'ICD9Dx')      
     PROCDESC.VALID AS ISPROCVALID,             
     DIAGDESC.VALID AS ISDIAGVALID,        
     CASE WHEN PROCE.SEQUENCE =1 THEN 'Y' ELSE 'N' END AS PROC_PRIMARYCODE,          
     CASE WHEN DIAG.SEQUENCE =1 THEN 'Y' ELSE 'N' END AS DIAG_PRIMARYCODE ,        
     PROCE.SEQUENCE AS ProcedureSequence,        
     DIAG.SEQUENCE AS DiagSequence             
     from           
     --(          
      (          
       select distinct c.syskey as syskey          
       from snCPPACKAGEDEF C where domdef=@param1                      
        )x          

      left join SNCPPROCDEF proce  on (x.syskey=proce.CPPACKAGEDEF and proce.DOMDEF = @param1)          
      left join SNCPDIAGDEF diag  on (x.syskey=diag.CPPACKAGEDEF  and diag.DOMDEF = @param1)          
      left join SNLOCCP_DTPROC PROCDESC with(nolock)  ON (proce.PROCCODE = PROCDESC.PROCCODE and PROCDESC.valid='Y'   )      
      LEFT JOIN  SNLOCCP_DTDIAG DIAGDESC with(nolock)  ON (diag.DIAGCODE = DIAGDESC.DIAGCODE and  DIAGDESC.valid='Y')                                    
            ) P              

            ON T.SYSKEY = P.CPPACKAGEDEF            


      LEFT JOIN                   

      VWCODEDESC AS C ON  T.CPPACKAGE_PARAMS = C.CPPACKAGE_PARAMS              

      LEFT JOIN                 

            (SELECT DISTINCT  pkgRL.CPPACKAGEDEF, pkgRL.CHARGECODE, pkgRL.UNITS, pkgRL.UNITSORDAYS, pkgRL.SEQUENCE,               
                              pkgRL.PERRELEVANCE, CAST(ISNULL(pkgRL.MOD1,'') + ','+ ISNULL(pkgRL.MOD2,'') + ','+ ISNULL(pkgRL.MOD3,'')+ ','+ ISNULL(pkgRL.MOD4,'') AS VARCHAR(50)) AS MODIFIERS, pkgRL.UNITWEIGHT,               
                              ISNULL(pkgRL.REVDESC,'Procedure no longer exists!') AS REVDESC, pkgRL.HCPCSRATES,               
                              pkgRL.REVCODE, pkgRL.LINECHARGE, pkgRL.STATCHARGE, pkgRL.CDMCHARGE,               
                              CASE WHEN pkgRL.HCPCSRATES = '' OR pkgRL.HCPCSRATES IN (SELECT CODEFROM FROM #tempGLT1DET) THEN pkgRL.HCPCSRATES ELSE 'Invalid HCPCS Code:' + pkgRL.HCPCSRATES  END AS 'CPT4'                         
                        FROM #SNCPPACKAGERL pkgRL ) revcode                  

                  ON T.SYSKEY = revcode.CPPACKAGEDEF            
                  where          
                  --(ISNULL(p.PROCCODE,'')<>'' OR ISNULL(p.DIAGCODE,'')<>'')         
                        --AND    
      ISNULL(ISDIAGVALID,'Y')='Y' AND ISNULL(ISPROCVALID,'Y')='Y'        


and      
(      

                  (       
                          (        
                                  (T.some_ver='9' AND ISNULL(p.diagcode_version,'ICD9Dx')='ICD9Dx'  )        
                                       OR        
                                  (T.some_ver='0' AND p.diagcode_version='ICD10CM')      
                                  OR       
                                    (ISNULL(P.DIAGCODE,'')='')      

                          )         
                          AND        
                          (        
                               (T.some_ver='9' AND ISNULL(p.proccode_version,'ICD9Proc')='ICD9Proc' )        
                               OR        
                               (T.some_ver='0' AND p.proccode_version='ICD10PCS')       
                               OR      
                               (ISNULL(P.PROCCODE,'')='')      

                          )        
                  )       
                  OR      
                  ((ISNULL(P.DIAGCODE,'')='')OR(ISNULL(P.PROCCODE,'')='') )      

)                                                                                                                                        
  ORDER BY CASE            
        WHEN UPPER(@SORTFIELD) = 'DESCRIPTION' AND            
          @SORTDIRECTION = 'DESC' THEN T.DESCRIPTION            
      END DESC,            

      CASE            
        WHEN UPPER(@SORTFIELD) = 'DESCRIPTION' AND            
          @SORTDIRECTION != 'DESC' THEN T.DESCRIPTION            
      END ASC,            

      CASE            
        WHEN UPPER(@SORTFIELD) = 'CHARGECODE' AND            
          @SORTDIRECTION = 'DESC' THEN             
          T.SYSKEY             
      END DESC,            

      CASE            
        WHEN UPPER(@SORTFIELD) = 'CHARGECODE' AND            
          @SORTDIRECTION != 'DESC' THEN             
          T.SYSKEY            
      END ASC            

END  

在程序中,param1和param2是必需的。当我用其余的参数搜索时,我的程序给了我平均表现(10-12秒)。但是当我用param10搜索时,我得到了16分钟的结果,这是不可接受的。我试图通过更改where子句位置来调整过程,实现临时表但没有帮助。

建议一些只能param10才能提高效果的方法。

1 个答案:

答案 0 :(得分:0)

尝试在REVDET.HCPCSRATES上创建索引,然后在snVwCodeXWalk.SOURCECODE上创建索引。首先尝试一个,然后尝试另一个,然后两个,看看它有什么效果。