如何提高已加入查询的成本

时间:2014-12-22 10:23:50

标签: mysql

我在sql中有一个查询,需要40分钟才能回复!

任何有关调整此建议的建议都将受到赞赏。

select    
      QA.*,
      QB.Tedade_Forushe_Ensheab 
   from
     ( ( SELECT
              dbo.MiladiTOShamsi(GETDATE()) AS CURENT_DATE, 
              '93/01/15' AS F_DATE, 
              '93/01/20' AS T_DATE, 
              E.title, 
              E.code as EsterCode,
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.req_date, M.install_date )) AS TOTAL_DAY,
              COUNT(*) AS CNT,
              COUNT(R.req_seq) AS Req_seq_Count, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.req_date, R.actv_date )) / COUNT(*) AS AVR_1, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.visit_date, R.actv_date )) / COUNT(*) AS AVR_2, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.pay_date, R.actv_date )) / COUNT(*) AS AVR_3, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.visit_date, R.pay_date )) / COUNT(*) AS AVR_4, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.req_date, R.visit_date )) / COUNT(*) AS AVR_5, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.req_date, R.pay_date )) / COUNT(*) AS AVR_6, 
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.actv_date, R.create_actv_date )) / COUNT(*) AS AVR_7,
              SUM( dbo.fn_ShamsiDateStrDiffDay( R.actv_date, M.first_date )) / COUNT(*) AS AVR_8
           FROM 
              tby_1_request AS R 
                 INNER JOIN y_1_tariff AS T 
                    ON R.tariff_type = T.tariff 
                 INNER JOIN tby_1_meter AS M 
                    ON R.cust_id = M.cust_id 
                 INNER JOIN tby_1_estr AS E 
                    ON R.estr = E.code
           WHERE
                  R.net_status = 3
              AND R.actv_date >= '93/01/15'
              AND R.actv_date <= '93/01/20'
              AND R.pay_date >= '93/01/15'
              AND R.pay_date <= '93/01/20'
           GROUP BY 
              E.title, 
              E.code ) AS QA

      left join
      ( Select 
              A.*,
              B.Tedade_Forushe_Ensheab,
              C.Tedade_Nasbfrom,
              D.Tedade_ijade_sabegeh 
           from
              ( select distinct Estr.title
                   from  tby_1_request Req
                      INNER JOIN tby_1_estr AS Estr 
                         ON Req.estr = Estr.code
                      INNER JOIN y_1_tariff AS T 
                         ON Req.tariff_type = T.tariff 
                      INNER JOIN tby_1_meter AS M 
                         ON Req.cust_id = M.cust_id
                   group by 
                      Estr.title,
                      Estr.code,
                      Req.pay_date,
                      Req.net_status,
                      Req.actv_date
                   having 
                          Req.net_status = 3
                      AND Req.actv_date >= '93/01/15'
                      AND Req.actv_date <= '93/01/20'
                      AND Req.pay_date >= '93/01/15'
                      AND Req.pay_date <= '93/01/20' ) AS A

      left join
      ( select
              Estr.title,
              COUNT( CASE WHEN Pay_date IS NOT NULL AND Req.pay_date >= '93/01/15' AND Req.pay_date <= '93/01/20' 
                          THEN 1 ELSE NULL END) AS Tedade_Forushe_Ensheab
           from  
              tby_1_request Req
                 INNER JOIN tby_1_estr AS Estr 
                    ON Req.estr = Estr.code
           group by 
              Estr.title,
              Estr.code) AS B 
           ON A.title = B.title


      left join
      ( select 
              Estr.title,
              COUNT( CASE WHEN actv_date IS NOT NULL AND Req.actv_date >= '93/01/15' AND Req.actv_date <= '93/01/20' 
                          THEN 1 ELSE NULL END) AS Tedade_Nasbfrom 
           from 
              tby_1_request Req
                 INNER JOIN tby_1_estr AS Estr 
                    ON Req.estr = Estr.code
           group by 
              Estr.title,
              Estr.code ) AS C 
           ON A.title = C.title


      left join
      ( select 
              Estr.title,
              COUNT( CASE WHEN create_actv_date IS NOT NULL AND Req.create_actv_date >= '93/01/15' AND Req.create_actv_date <= '93/01/20' 
                          THEN 1 ELSE NULL END ) AS Tedade_ijade_sabegeh
           from  
              tby_1_request Req
                 INNER JOIN tby_1_estr AS Estr 
                    ON Req.estr = Estr.code
           group by 
              Estr.title,
              Estr.code ) AS D 
           ON A.title = D.title ) AS QB 
       On QA.title = Qb.title

1 个答案:

答案 0 :(得分:0)

为了便于阅读,我编辑了原始SQL查询。我重新调整了,似乎错过了一个双重开放的内部A-D左连接查询。

此外,在不知道表结构或可用索引的情况下,我将确保在您的tby_1_request表上,您有一个索引(net_status,actv_date,pay_date)来帮助您的WHERE标准。另外,对于计数的B,C和D查询,我会在(pay_date,estr),(actv_date,estr)和(create_actv_date,estr)上有单独的索引

仔细观察一下,你也得到了一个笛卡尔结果,可能会因为你的查询按标题和代码分组而被杀,但你只是加入了标题栏。