提高SQL Server性能的几种实用技术

发表于:2009-6-11 11:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

分享:

  拾遗补零

  这里介绍其他一些可帮助提高 SQL 查询效率的常用技术。假设您将按区域对所有销售人员进行分组并将他们的销售额进行小计,但是您只想要那些数据库中标记为处于活动状态的销售人员。您可以按区域对销售人员分组,并使用 HAVING 子句消除那些未处于活动状态的销售人员,也可以在 WHERE 子句中执行此操作。在 WHERE 子句中执行此操作会减少需要分组的行数,所以比在 HAVING 子句中执行此操作效率更高。HAVING 子句中基于行的条件的筛选会强制查询对那些在 WHERE 子句中会被去除的数据进行分组。

  另一个提高效率的技巧是使用 DISTINCT 关键字查找数据行的单独报表,来代替使用 GROUP BY 子句。在这种情况下,使用 DISTINCT 关键字的 SQL 效率更高。请在需要计算聚合函数(SUM、COUNT、MAX 等)的情况下再使用 GROUP BY。另外,如果您的查询总是自己返回一个唯一的行,则不要使用 DISTINCT 关键字。在这种情况下,DISTINCT 关键字只会增加系统开销。

  您已经看到了,有大量技术都可用于优化查询和实现特定的业务规则,技巧就是进行一些尝试,然后比较它们的性能。最重要的是要测试、测试、再测试。

  Figure 2 Returning All Customers and Their Sales

  set nocount on

  DECLARE @dtStartDate DATETIME,

  @dtEndDate DATETIME,

  @dtDate DATETIME

  SET @dtEndDate = '5/5/1997'

  SET @dtEndDate = DATEADD(DD, -1, CAST(CAST((MONTH(@dtEndDate) + 1)

  AS VARCHAR(2)) + '/01/' + CAST(YEAR(@dtEndDate) AS VARCHAR(4)) + '

  23:59:59' AS DATETIME))

  SET @dtStartDate = DATEADD(MM, -1 * 12, @dtEndDate)

  SELECT CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

  CASE

  WHEN MONTH(o.OrderDate) < 10

  THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  END AS sMonth,

  c.CustomerID,

  c.CompanyName,

  c.ContactName,

  SUM(od.Quantity * od.UnitPrice) AS mSales

  FROM Customers c

  INNER JOIN Orders o ON c.CustomerID = o.CustomerID

  INNER JOIN [Order Details] od ON o.OrderID = od.OrderID

  WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

  GROUP BY

  CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

  CASE

  WHEN MONTH(o.OrderDate) < 10

  THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  END,

  c.CustomerID,

  c.CompanyName,

  c.ContactName

  ORDER BY

  c.CompanyName,

  sMonth

  Figure 3 Cartesian Product at Work

  DECLARE @tblMonths TABLE (sMonth VARCHAR(7))

  DECLARE @tblCustomers TABLE ( CustomerID CHAR(10),

  CompanyName VARCHAR(50),

  ContactName VARCHAR(50))

  DECLARE @tblFinal TABLE ( sMonth VARCHAR(7),

  CustomerID CHAR(10),

  CompanyName VARCHAR(50),

  ContactName VARCHAR(50),

  mSales MONEY)

  DECLARE @dtStartDate DATETIME,

  @dtEndDate DATETIME,

  @dtDate DATETIME,

  @i INTEGER

  SET @dtEndDate = '5/5/1997'

  SET @dtEndDate = DATEADD(DD, -1,

  CAST(CAST((MONTH(@dtEndDate) + 1) AS

  VARCHAR(2)) + '/01/' + CAST(YEAR(@dtEndDate) AS VARCHAR(4)) + '

  23:59:59' AS DATETIME))

  SET @dtStartDate = DATEADD(MM, -1 * 12, @dtEndDate)

  — Get all months into the first table

  SET @i = 0

  WHILE (@i < 12)

  BEGIN

  SET @dtDate = DATEADD(mm, -1 * @i, @dtEndDate)

  INSERT INTO @tblMonths SELECT

  CAST(YEAR(@dtDate) AS VARCHAR(4)) + '-' +

  CASE

  WHEN MONTH(@dtDate) < 10

  THEN '0' + CAST(MONTH(@dtDate) AS VARCHAR(2))

  ELSE CAST(MONTH(@dtDate) AS VARCHAR(2))

  END AS sMonth

  SET @i = @i + 1

  END

  — Get all clients who had sales during

  that period into the "y" table

  INSERT INTO @tblCustomers

  SELECT DISTINCT

  c.CustomerID,

  c.CompanyName,

  c.ContactName

  FROM Customers c

  INNER JOIN Orders o ON c.CustomerID = o.CustomerID

  WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

  INSERT INTO @tblFinal

  SELECT m.sMonth,

  c.CustomerID,

  c.CompanyName,

  c.ContactName,

  0

  FROM @tblMonths m CROSS JOIN @tblCustomers c

  UPDATE @tblFinal SET

  mSales = mydata.mSales

  FROM @tblFinal f INNER JOIN

  (

  SELECT c.CustomerID,

  CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

  CASE WHEN MONTH(o.OrderDate) < 10

  THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  END AS sMonth,

  SUM(od.Quantity * od.UnitPrice) AS mSales

  FROM Customers c

  INNER JOIN Orders o ON c.CustomerID = o.CustomerID

  INNER JOIN [Order Details] od ON o.OrderID = od.OrderID

  WHERE o.OrderDate BETWEEN @dtStartDate AND @dtEndDate

  GROUP BY

  c.CustomerID,

  CAST(YEAR(o.OrderDate) AS VARCHAR(4)) + '-' +

  CASE WHEN MONTH(o.OrderDate) < 10

  THEN '0' + CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  ELSE CAST(MONTH(o.OrderDate) AS VARCHAR(2))

  END

  ) mydata on f.CustomerID = mydata.CustomerID AND f.sMonth =

  mydata.sMonth

  SELECT f.sMonth,

  f.CustomerID,

  f.CompanyName,

  f.ContactName,

  f.mSales

  FROM @tblFinal f

  ORDER BY

  f.CompanyName,

  f.sMonth

33/3<123
重磅发布,2022软件测试行业现状调查报告~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号