科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道JAVA进阶--五种提高 SQL 性能的方法

JAVA进阶--五种提高 SQL 性能的方法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

内嵌视图 -使用内嵌视图取代临时表。内嵌视图只是一个可以联接到 FROM 子句中的查询。如果只需要将数据联接到其他查询,则可以试试使用内嵌视图,以节省资源。

作者:okhero 来源:IT专家网 2008年4月12日

关键字: 方法 提高 SQL java

  • 评论
  • 分享微博
  • 分享邮件
1, 从 INSERT 返回 IDENTITY

  SELECT @@IDENTITY

  2, 内嵌视图与临时表

  临时表 - 在 tempdb 中的临时表会导致查询进行大量 I/O 操作和磁盘访问,临时表会消耗大量资源。

  内嵌视图 -使用内嵌视图取代临时表。内嵌视图只是一个可以联接到 FROM 子句中的查询。如果只需要将数据联接到其他查询,则可以试试使用内嵌视图,以节省资源。

  3, 避免 LEFT JOIN 和 NULL

  LEFT JOIN 消耗的资源非常之多,因为它们包含与 NULL(不存在)数据匹配的数据。在某些情况下,这是不可避免的,但是代价可能非常高。LEFT JOIN 比 INNER JOIN 消耗资源更多,所以如果您可以重新编写查询以使得该查询不使用任何 LEFT JOIN,则会得到非常可观的回报。

  加快使用 LEFT JOIN 的查询速度的一项技术涉及创建一个 TABLE 数据类型,插入第一个表(LEFT JOIN 左侧的表)中的所有行,然后使用第二个表中的值更新 TABLE 数据类型。此技术是一个两步的过程,但与标准的 LEFT JOIN 相比,可以节省大量时间。一个很好的规则是尝试各种不同的技术并记录每种技术所需的时间,直到获得用于您的应用程序的执行性能最佳的查询。

  DECLARE @tblMonths TABLE (sMonth VARCHAR(7))

  4, 灵活使用笛卡尔乘积

  对于此技巧,我将进行非常详细的介绍,并提倡在某些情况下使用笛卡尔乘积。出于某些原因,笛卡尔乘积 (CROSS JOIN) 遭到了很多谴责,开发人员通常会被警告根本就不要使用它们。在许多情况下,它们消耗的资源太多,从而无法高效使用。但是像 SQL 中的任何工具一样,如果正确使用,它们也会很有价值。

  其中一段示例代码,值得效仿:

  -- 笛卡尔乘积则可以返回所有月份的所有客户。笛卡尔乘积基本上是将第一个表与第二个表相乘,生成一个行集合,其中包含第一个表中的行数与第二个表中的行数相乘的结果。因此,笛卡尔乘积会向表 @tblFinal 返回 12(所有月份)*81(所有客户)=972 行。最后的步骤是使用此日期范围内每个客户的月销售额总计更新 @tblFinal 表,以及选择最终的行集。

  

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

 5, 拾遗补零

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

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

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章