2016-08-20 58 views
1

TitemName的执行时间和TshotName是这里的问题如何减少SQL SELECT查询

SELECT DISTINCT 
    tJobs.* , 
    tCustomer.Name AS Customer_name , 
    (SELECT tEmployee.First + ' ' + tEmployee.Last 
    FROM tEmployee 
    WHERE tEmployee.EmployeeID = tJobs.AccountExecutiveID) AS AccountExecutive, 
    (SELECT tEmployee.First + ' ' + tEmployee.Last 
    FROM tEmployee 
    WHERE tEmployee.EmployeeID = tJobs.AccountManagerID) AS AccountManager, 
    dbo.RetrunUserFavourite(tJobs.JobNumber, 33369, 'Employee') AS Favorites, 
    (SELECT COUNT(*) 
    FROM tShots 
    WHERE tShots.JobNumber = tJobs.JobNumber) AS shotcount, 
    SUBSTRING((SELECT ', ' + SKU + ', ' + Source + ', ' + ModelNumber 
          + ', ' + Description 
       FROM tItems 
       WHERE tItems.CustomerID = tCustomer.CustomerID 
       FOR XML PATH('')), 3, 200000) titemName, 
    SUBSTRING((SELECT ', ' + ArtDirection + ', ' 
          + REPLACE(CONVERT(VARCHAR(5), AdDate, 110), '-', 
             '/') 
       FROM tShots 
       WHERE tShots.JobNumber = tJobs.JobNumber 
       FOR XML PATH('')), 3, 200000) TshotName 
FROM  
    tJobs 
INNER JOIN 
    tCustomer ON tCustomer.CustomerID = tJobs.CustomerID 
WHERE 
    tCustomer.CustomerID = 68666 
+0

你已经索引(理想覆盖):

tItems(CustomerID) 

和? –

+0

次要的事情:不要用格式110调用CONVERT,然后用斜杠替换破折号,为什么不直接使用格式1或101直接生成斜杠。 –

+0

这里我使用这段代码,但问题是执行时间不减少。我的问题是在(tItems)表2641数据和(tshots)表13585数据加入这两个表时,然后查询执行时间增加..所以如何解决这个问题 –

回答

1

你有非常多的字符串处理事情的是你查询,反正你的查询看起来会是一个略微改进版像...

Select DISTINCT 
     tJobs.* 
     , tCustomer.Name    AS Customer_name 
     , AE.First + ' ' + AE.Last AS AccountExecutive 
     , AM.First + ' ' + AM.Last AS AccountManager 
     , dbo.RetrunUserFavourite(tJobs.JobNumber,33369,'Employee')AS Favorites 
     , TS.shotcount 
     , SUBSTRING((SELECT ', ' + SKU + ', ' + Source + ', ' + ModelNumber+ ', ' + Description 
        FROM tItems 
        where tItems.CustomerID=tCustomer.CustomerID 
        FOR XML PATH('')), 3, 200000)titemName 
    , SUBSTRING((SELECT ', ' + ArtDirection +', '+REPLACE(CONVERT(VARCHAR(5),AdDate,110), '-','/') 
        FROM tShots 
        where tShots.JobNumber=tJobs.JobNumber 
        FOR XML PATH('')), 3, 200000)TshotName 
From tJobs 
inner join tCustomer on tCustomer.CustomerID = tJobs.CustomerID 
Left join tEmployee AE ON AE.EmployeeID = tJobs.AccountExecutiveID 
Left join tEmployee AM ON AM.EmployeeID = tJobs.AccountManagerID 
Left join (
      SELECT JobNumber , Count(*) shotcount 
      FROM tShots 
      GROUP BY JobNumber 
     ) TS ON TS.JobNumber = tJobs.JobNumber 
WHERE tCustomer.CustomerID = 68666 

指针的情侣:

  1. 在您的select语句中有子查询会导致效率非常低,因为子查询是针对外部查询返回的每一行执行的,所以更明智的做法是使用连接。

  2. 你也可以在你的select中调用用户定义的标量函数dbo.RetrunUserFavourite(),这些标量UDF也是性能杀手,这里再次应用相同的执行逻辑,它们也针对外部返回的每一行执行查询,更合理的方法是将函数逻辑/代码放入CTE中,并将您的查询加入该CTE。

  3. 这些逗号分隔的列表是您为最后两列实时创建的列表,速度会很慢,也许Inline-Table-Valued函数可以在此处提供更好的性能。

+0

是的,我同意你只是给我一个想法如何使用的东西在这里选择DISTINCT tJobs。* 从tJobs 内部联接tCustomer的上tCustomer.CustomerID = tJobs.CustomerID LEFT JOIN 作为标签 上tab.JobNumber = tJobs.JobNumber(从tShots组由jobnumber可以,AdDate选择jobnumber可以,AdDate)左加入 (从客户ID,SKU中选择客户ID,SKU)作为tab1 tab1.CustomerID = tJobs.CustomerID 其中tCustomer.CustomerID = 68666 –

1

我非常同意M Ali的评论。我会做两点。首先不是关于表现。但是,不是substring()使用:

STUFF((SELECT ', ' + SKU + ', ' + Source + ', ' + ModelNumber+ ', ' + Description 
     FROM tItems 
     WHERE tItems.CustomerID = tCustomer.CustomerID 
     FOR XML PATH('') 
     ), 1, 1, '') as titemName 

这样,你不需要奇怪的,毫无意义的数字左右浮动的代码。

其次,您可能需要索引。基于高亮显示的性能问题,我建议:在`WHERE`子句引用的列

tshots(JobNumber, ArtDirection, AdDate)