连接表的低效SQL查询

时间:2015-09-21 09:46:45

标签: sql-server

我有一个包含1700行数据的表。我正在使用下面的查询来查询它,它也从相关表中提取了补充数据。它目前运行非常缓慢(大约10秒)。

如何提高此查询的效率?

SELECT [jobID] ,

  (SELECT orgname
   FROM pm_clients c
   WHERE c.orgID IN
       (SELECT orgid
        FROM pm_jobs j
        WHERE j.jobid=t.jobid
          AND j.jobStatus>=13)) AS orgname ,

  (SELECT sector
   FROM pm_clients c
   WHERE c.orgID IN
       (SELECT orgid
        FROM pm_jobs j
        WHERE j.jobid=t.jobid
          AND j.jobStatus>=13)) AS sector ,

  (SELECT region= CASE country
                      WHEN 1 THEN region
                      ELSE
                             (SELECT countryname
                              FROM AT_A_CountryCodes x
                              WHERE x.id= l.country)
                  END
   FROM PM_ClientDetails l
   WHERE l.userid =
       (SELECT userid
        FROM pm_jobs j
        WHERE j.jobid=t.jobid)) AS region ,

  (SELECT postcode
   FROM PM_ClientDetails l
   WHERE l.userid =
       (SELECT userid
        FROM pm_jobs j
        WHERE j.jobid=t.jobid)) AS postcode ,

  (SELECT firstname
   FROM users u
   WHERE u.userid =
       (SELECT pmid
        FROM pm_jobs j
        WHERE j.jobid=t.jobid)) AS PM ,
       [creationDate] ,

  (SELECT statusName
   FROM pm_jobstatus j
   WHERE j.[statusID]=t.jobStatus) AS JobStatus ,
       [completionDate] ,
       [deadline],
       [jobTitle] ,

  (SELECT currencysymbol
   FROM at_a_currency c
   WHERE c.currencyID =
       (SELECT top(1) quoteCurrency
        FROM PM_Quotes q
        WHERE q.taskid IN
            (SELECT taskid
             FROM pm_tasks x
             WHERE x.jobID=t.jobid))) AS currency ,

  (SELECT sum(quoteSubTotal)
   FROM PM_Quotes q
   WHERE q.taskid IN
       (SELECT taskid
        FROM pm_tasks x
        WHERE x.jobID=t.jobid)) AS subtotal ,

  (SELECT sum(quoteVAT)
   FROM PM_Quotes q
   WHERE q.taskid IN
       (SELECT taskid
        FROM pm_tasks x
        WHERE x.jobID=t.jobid)) AS VAT ,

  (SELECT sum(quoteTotal)
   FROM PM_Quotes q
   WHERE q.taskid IN
       (SELECT taskid
        FROM pm_tasks x
        WHERE x.jobID=t.jobid)) AS total ,

  (SELECT [purchaseOrder]
   FROM pm_jobs j
   WHERE j.jobid=t.jobid) AS purchaseOrder ,

  (SELECT [clientReference]
   FROM pm_jobs j
   WHERE j.jobid=t.jobid) AS clientReference ,

  (SELECT CASE
              WHEN [deadline]='1900-01-01 00:00:00' THEN 1
              WHEN [completiondate]>dateadd(dd,1,[deadline]) THEN 0
              WHEN [completiondate]<=dateadd(dd,1,[deadline])THEN 1
              WHEN [completiondate] IS NULL THEN 0
          END) AS completedOnTime
FROM [PM_jobs] t
WHERE jobStatus>=13

修改

感谢@GuidoG的回复。这是修改后的查询,现在要快得多。

SELECT j.jobid, 
       c.orgname, 
       c.sector, 
       (SELECT region= CASE country 
                         WHEN 1 THEN region 
                         ELSE (SELECT countryname 
                               FROM   at_a_countrycodes x 
                               WHERE  x.id = l.country) 
                       END)                     AS region, 
       l.postcode, 
       (SELECT firstname 
        FROM   users u 
        WHERE  u.userid = J.pmid)               AS PM, 
       j.creationdate, 
       (SELECT statusname 
        FROM   pm_jobstatus x 
        WHERE  x.[statusid] = j.jobstatus)      AS JobStatus, 
       j.[completiondate], 
       j.[deadline], 
       j.[jobtitle], 
       j.purchaseorder, 
       j.clientreference, 
       (SELECT currencysymbol 
        FROM   at_a_currency c 
        WHERE  c.currencyid = l.clientcurrency) AS currency, 
       Sum(q.quotesubtotal)                     AS subtotal, 
       Sum(q.quotevat)                          AS VAT, 
       Sum(q.quotetotal)                        AS total, 
       (SELECT CASE 
                 WHEN j.[deadline] = '1900-01-01 00:00:00' THEN 1 
                 WHEN j.[completiondate] > Dateadd(dd, 1, j.[deadline]) THEN 0 
                 WHEN j.[completiondate] <= Dateadd(dd, 1, j.[deadline])THEN 1 
                 WHEN j.[completiondate] IS NULL THEN 0 
               END)                             AS completedOnTime, 
       Count(t.taskid)                          AS taskcount 
FROM   [pm_jobs] j 
       INNER JOIN pm_clients c 
               ON j.orgid = c.orgid 
       INNER JOIN pm_clientdetails l 
               ON j.userid = l.userid 
       INNER JOIN pm_tasks t 
               ON j.jobid = t.jobid 
       INNER JOIN pm_quotes q 
               ON q.taskid = t.taskid 
                  AND t.jobid = j.jobid 
WHERE  jobstatus >= 13 
GROUP  BY j.jobid, 
          c.orgname, 
          c.sector, 
          l.country, 
          l.region, 
          l.postcode, 
          l.firstname, 
          j.creationdate, 
          j.jobstatus, 
          j.completiondate, 
          j.deadline, 
          j.jobtitle, 
          j.purchaseorder, 
          j.clientreference, 
          l.clientcurrency, 
          J.pmid 
ORDER  BY completiondate DESC 

1 个答案:

答案 0 :(得分:1)

您应该考虑加入而不是替换。这是一个让你走上正轨的小例子:

SELECT  t.jobID ,
        c.orgName,
        c.sector
FROM [SQL2012_921487_atlas].[dbo].[PM_jobs] t
  inner join pm_clients c on t.orgID = c.orgID
WHERE jobStatus>=13

当像你一样进行子查询时,强制SQL Server多次读取表pm_clients; join使它只能读取pm_clients一次。