首页 | 登录 | 注册 | 会员中心 | 网站地图
  当前位置:首页 >> 网管 >> 数据库 >> SQL Server >> 冗长的SQL Server查询将消耗你的CPU
冗长的SQL Server查询将消耗你的CPU
来源:IT专家网 作者: 发布时间:2008-09-25

  问题

  只要看看数据管理和关系型数据库管理系统规则,就发现关系型数据库是使用一个合理级别的并发来维护数据和当支持数据管理行为例如备份、成批清除、改变数据结构等等时的最合适的方法。

  一个问题是在传统应用程序中编程语言的不同。SQL(结构化查询语言)语言是一个声明性语言,在大多数公司里,它成为了用于描述“我需要什么”和“从哪里获取”的“数据语言”。OOP(面向对象编程)语言成为了全世界R&D(研究和开发)公司的开发人员最普遍采用的语言。那么我们怎样弥补这个差距呢?

  专家解答

  这两个趋势使得需要一个弥补这个差距的“桥”,它是通过将请求从面向对象语言翻译成SQL来弥补的。在大多数情况下,DAL(数据访问层)是用来描述以一种集中方式管理所有这些“数据拼接任务”的机制的。

  数据库供应商(Microsoft、Oracle、IBM等等)因其对SQL的特别喜爱而提供了众多私有命令,在DAL中的翻译就需要支持许多选项。而最后的结果是执行有时会失去内嵌到引擎中的性能优化。这使得许多这样的DAL以一种非常直接的方式被执行,它将这个请求分解成许多小段,它们各自被翻译成相应的SQL语句并建立将要象征性地进行这项工作的“SELECT…FROM…WHERE…”条件从句。

  “机器编写的SQL语句”有时会是很长的文本语句。在32位和64位系统上,包含SQL语句的字符串长度是定义为65,536 *网络数据包大小。默认的网络数据包大小为4096,所以SQL语句文本限制为256MB。

  我怀疑长文本查询(远小于256MB)将会对服务器的CPU造成负担。所以我在这篇文章中进行测试和公布。在这篇文章里,我将介绍介绍一下内容:

  •   证明长文本查询将会消耗你的CPU。
  •   给出关于在一个中等大小服务器上预计的实际消耗的理解。
    •   具有2GB RAM和4 x 10,000 RPM磁盘的双核CPU。

  测试表特征

  为了测试,我将创建一个有200,000行记录的表(叫做t1000)。这个表有许多不同的数据类型,因为我认为这可以合理地表现生产环境中的一个普通表。这个表的特征包括:

  •   一个单独的integer字段作为主键(默认为蔟索引)。
  •   一个varchar字段。
  •   一个模拟额外1KB数据的char字段。
  •   五个用来创建WHERE条件从句中长文本查询的integer字段。

  脚本:创建测试表


  create table t1000 (
  c1 int not null constraint test_pk primary key,
  c2 varchar(10) not null,
  c3 char(1000),
  c4 int not null,
  c5 int not null,
  c6 int not null,
  c7 int not null,
  c8 int not null
  )
  go

 脚本:组装测试表


  set nocount on
  declare @i as int
  set @i = 0
  while @i<200000
  begin
  set @i = @i + 1
  insert into t1000 (c1, c2, c3, c4, c5, c6, c7, c8)
  values (@i,
  cast (@i as varchar (10)),
  '...simulating additional 1k data...',
  @i, @i, @i, @i, @i)
  end
  set nocount off
  go

  脚本:创建测试查询

  因为我计划测试一些很长的查询,所以我将以自动的方式生成它们。我首先只是想将一些较长文本打印到屏幕上然后将它黏贴到一个新的SQL Server管理套件查询窗口中。但我发现较长的查询(几百KB)对于管理套件来说是个沉重的负担(特别是当自动换行打开的时候),所以我转向另一个更好的东西——文件。

  可以采用多种编程语言来写文本文件,但是因为我们要使用SQL Server,所以我将介绍一个T-SQL方法。我将使用下面的存储过程。


  create PROCEDURE spWriteStringToFile
  (@String Varchar(max), --8000 in SQL Server 2000
  @Path VARCHAR(255),
  @Filename VARCHAR(100)
  )
  AS
  DECLARE @objFileSystem int
  ,@objTextStream int,
  @objErrorObject int,
  @strErrorMessage Varchar(1000),
  @Command varchar(1000),
  @hr int,
  @fileAndPath varchar(80)
  set nocount on
  select @strErrorMessage='opening the File System Object'
  EXECUTE @hr = sp_OACreate 'Scripting.FileSystemObject' , @objFileSystem OUT
  Select @FileAndPath=@path+''+@filename
  if @HR=0 Select @objErrorObject=@objFileSystem , @strErrorMessage='Creating file "'+@FileAndPath+'"'
  if @HR=0 execute @hr = sp_OAMethod @objFileSystem , 'CreateTextFile'
  , @objTextStream OUT, @FileAndPath,2,True
  if @HR=0 Select @objErrorObject=@objTextStream,
  @strErrorMessage='writing to the file "'+@FileAndPath+'"'
  if @HR=0 execute @hr = sp_OAMethod @objTextStream, 'Write', Null, @String
  if @HR=0 Select @objErrorObject=@objTextStream, @strErrorMessage='closing the file "'+@FileAndPath+'"'
  if @HR=0 execute @hr = sp_OAMethod @objTextStream, 'Close'
  if @hr<>0
  begin
  Declare
  @Source varchar(255),
  @Description Varchar(255),
  @Helpfile Varchar(255),
  @HelpID int
  EXECUTE sp_OAGetErrorInfo @objErrorObject,
  @source output,@Description output,@Helpfile output,@HelpID output
  Select @strErrorMessage='Error whilst '
  +coalesce(@strErrorMessage,'doing something')
  +', '+coalesce(@Description,'')
  raiserror (@strErrorMessage,16,1)
  end
  EXECUTE sp_OADestroy @objTextStream
  EXECUTE sp_OADestroy @objTextStream
  GO

  脚本:激活OLE自动化

  因为上面的存储过程使用了OLE自动化,所以你需要在你的SQL Server上激活它,因为这个选项基于安全考虑默认情况下是关闭的。使用下面的命令来打开OLE自动化:


  EXEC sp_configure 'Ole Automation Procedures', 1
  RECONFIGURE WITH OVERRIDE
  GO

  如果你的服务器没有激活OLE自动化,那么运行上面的存储过程将产生下面的错误:


  Msg 15281, Level 16, State 1, Procedure sp_OACreate, Line 1
  SQL Server blocked access to procedure 'sys.sp_OACreate' of component 'Ole Automation Procedures' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ole Automation Procedures' by using sp_configure. For more information about enabling 'Ole Automation Procedures', see "Surface Area Configuration" in SQL Server Books Online.

  脚本:我应该在我的测试表上采用什么SQL语句?

  我想写一个简单的查询,它只返回一条记录但具有很长的WHERE条件从句。下面是一个示例查询:


  select top 1 c1
  from t1000
  where c1 > 0
  or (c5 = 1)
  or (c6 = 2)
  or (c7 = 3)
  or (c8 = 4)
  or (c4 = 5)
  or (c5 = 6)
  or (c6 = 7)
  or (c7 = 8)
  or (c8 = 9)
  or (c4 = 10)
  GO
(责任编辑:IORI)
网友评论
评论加载中…
快速检索
推荐专题
Linux中文环境——专题
漏洞扫描全搜索
Solaris 基础知识入门——专题
注册表 入门基础及修改技巧
友情链接 | 欢迎投稿 | 杂志发行 | 广告报价 | 人才招聘 | 服务条款 | 免责声明 | 隐私保护 | 关于网管员世界
CopyRight © 2001-2008 [网管员世界 www.365master.com] All Rights Reserved.
《网管员世界》杂志,专为网管服务的刊物!