海量数据库的查询优化及分页算法计划ITeye - 威尼斯人

海量数据库的查询优化及分页算法计划ITeye

2019-01-12 14:11:38 | 作者: 静曼 | 标签: 分页,查询,数据 | 浏览: 1798

许多人不知道SQL句子在SQL SERVER中是怎么履行的,他们忧虑自己所写的SQL句子会被SQL SERVER误解。比方:
select * from table1 where name=zhangsan and tID 10000
和履行:
select * from table1 where tID 10000 and name=zhangsan
一些人不知道以上两条句子的履行功率是否相同,因为假如简略的从句子先后上看,这两个句子的确是不相同,假如tID是一个聚合索引,那么后一句仅仅从表的10000条今后的记载中查找就行了;而前一句则要先从全表中查找看有几个name=zhangsan的,然后再依据束缚条件条件tID 10000来提出查询成果。
现实上,这样的忧虑是不必要的。SQL SERVER中有一个“查询剖析优化器”,它可以计算出where子句中的查找条件并断定哪个索引能缩小表扫描的查找空间,也就是说,它能完结主动优化。
尽管查询优化器可以依据where子句主动的进行查询优化,但咱们依然有必要了解一下“查询优化器”的作业原理,如非这样,有时查询优化器就会不依照您的原意进行快速查询。
在查询剖析阶段,查询优化器检查查询的每个阶段并决议束缚需求扫描的数据量是否有用。假如一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的,并且可以运用索引快速取得所需数据。
SARG的界说:用于束缚查找的一个操作,因为它通常是指一个特定的匹配,一个值得规模内的匹配或许两个以上条件的AND衔接。方式如下:
列名 操作符 常数 或 变量

常数 或 变量 操作符列名
列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边。如:
Name=’张三’
价格 5000
5000 价格
Name=’张三’ and 价格 5000
假如一个表达式不能满意SARG的方式,那它就无法束缚查找的规模了,也就是SQL SERVER有必要对每一行都判别它是否满意WHERE子句中的一切条件。所以一个索引关于不满意SARG方式的表达式来说是无用的。
介绍完SARG后,咱们来总结一下运用SARG以及在实践中遇到的和某些材料上定论不同的经历:

1、Like句子是否归于SARG取决于所运用的通配符的类型
如:name like ‘张%’ ,这就归于SARG

而:name like ‘%张’ ,就不归于SARG。

原因是通配符%在字符串的注册使得索引无法运用。

2、or 会引起全表扫描
Name=’张三’ and 价格 5000 符号SARG,而:Name=’张三’ or 价格 5000 则不契合SARG。运用or会引起全表扫描。

3、非操作符、函数引起的不满意SARG方式的句子
不满意SARG方式的句子最典型的状况就是包含非操作符的句子,如:NOT、!=、 、! 、! 、NOT EXISTS、NOT IN、NOT LIKE等,别的还有函数。下面就是几个不满意SARG方式的比如:

ABS(价格) 5000

Name like ‘%三’

有些表达式,如:

WHERE 价格*2 5000

SQL SERVER也会认为是SARG,SQL SERVER会将此式转化为:

WHERE 价格 2500/2

但咱们不引荐这样运用,因为有时SQL SERVER不能确保这种转化与原始表达式是完全等价的。

4、IN 的效果适当与OR
句子:

Select * from table1 where tid in (2,3)



Select * from table1 where tid=2 or tid=3

是相同的,都会引起全表扫描,假如tid上有索引,其索引也会失效。

5、尽量少用NOT
6、exists 和 in 的履行功率是相同的
许多材料上都显现说,exists要比in的履行功率要高,一同应尽或许的用not exists来代替not in。但现实上,我实验了一下,发现二者无论是前面带不带not,二者之间的履行功率都是相同的。因为触及子查询,咱们实验这次用SQL SERVER自带的pubs数据库。运行前咱们可以把SQL SERVER的statistics I/O状况翻开。

(1)select title,price from titles where title_id in (select title_id from sales where qty 30)

该句的履行成果为:

表 sales。扫描计数 18,逻辑读 56 次,物理读 0 次,预读 0 次。

表 titles。扫描计数 1,逻辑读 2 次,物理读 0 次,预读 0 次。

(2)select title,price from titles where exists (select * from sales where sales.title_id=titles.title_id and qty 30)

第二句的履行成果为:

表 sales。扫描计数 18,逻辑读 56 次,物理读 0 次,预读 0 次。

表 titles。扫描计数 1,逻辑读 2 次,物理读 0 次,预读 0 次。

咱们从此可以看到用exists和用in的履行功率是相同的。

7、用函数charindex()和前面加通配符%的LIKE履行功率相同
前面,咱们谈到,假如在LIKE前面加上通配符%,那么将会引起全表扫描,所以其履行功率是低下的。但有的材料介绍说,用函数charindex()来代替LIKE速度会有大的进步,经我实验,发现这种阐明也是过错的:

select gid,title,fariqi,reader from tgongwen where charindex(刑侦支队,reader) 0 and fariqi 2004-5-5

用时:7秒,别的:扫描计数 4,逻辑读 7155 次,物理读 0 次,预读 0 次。

select gid,title,fariqi,reader from tgongwen where reader like % + 刑侦支队 + % and fariqi 2004-5-5

用时:7秒,别的:扫描计数 4,逻辑读 7155 次,物理读 0 次,预读 0 次。

8、union并不绝比照or的履行功率高
咱们前面现已谈到了在where子句中运用or会引起全表扫描,一般的,我所见过的材料都是引荐这儿用union来代替or。现实证明,这种说法关于大部分都是适用的。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=2004-9-16 or gid 9990000

用时:68秒。扫描计数 1,逻辑读 404008 次,物理读 283 次,预读 392163 次。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=2004-9-16

union

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid 9990000

用时:9秒。扫描计数 8,逻辑读 67489 次,物理读 216 次,预读 7499 次。

看来,用union在通常状况下比用or的功率要高的多。

但通过实验,笔者发现假如or两头的查询列是相同的话,那么用union则反倒和用or的履行速度差许多,尽管这儿union扫描的是索引,而or扫描的是全表。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=2004-9-16 or fariqi=2004-2-5

用时:6423毫秒。扫描计数 2,逻辑读 14726 次,物理读 1 次,预读 7176 次。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=2004-9-16

union

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where  fariqi=2004-2-5

用时:11640毫秒。扫描计数 8,逻辑读 14806 次,物理读 108 次,预读 1144 次。

9、字段提取要依照“需多少、提多少”的准则,防止“select *”
咱们来做一个实验:

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc

用时:4673毫秒

select top 10000 gid,fariqi,title from tgongwen order by gid desc

用时:1376毫秒

select top 10000 gid,fariqi from tgongwen order by gid desc

用时:80毫秒

由此看来,咱们每少提取一个字段,数据的提取速度就会有相应的进步。进步的速度还要看您抛弃的字段的巨细来判别。

10、count(*)不比count(字段)慢
某些材料上说:用*会计算一切列,明显要比一个国际的列名功率低。这种说法其实是没有依据的。咱们来看:

select count(*) from Tgongwen

用时:1500毫秒

select count(gid) from Tgongwen

用时:1483毫秒

select count(fariqi) from Tgongwen

用时:3140毫秒

select count(title) from Tgongwen

用时:52050毫秒

从以上可以看出,假如用count(*)和用count(主键)的速度是适当的,而count(*)却比其他任何除主键以外的字段汇总速度要快,并且字段越长,汇总的速度就越慢。我想,假如用count(*), SQL SERVER或许会主动查找最小字段来汇总的。当然,假如您直接写count(主键)将会来的更直接些。

11、order by按调集索引列排序功率最高
咱们来看:(gid是主键,fariqi是聚合索引列)

select top 10000 gid,fariqi,reader,title from tgongwen

用时:196 毫秒。 扫描计数 1,逻辑读 289 次,物理读 1 次,预读 1527 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid asc

用时:4720毫秒。 扫描计数 1,逻辑读 41956 次,物理读 0 次,预读 1287 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by gid desc

用时:4736毫秒。 扫描计数 1,逻辑读 55350 次,物理读 10 次,预读 775 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi asc

用时:173毫秒。 扫描计数 1,逻辑读 290 次,物理读 0 次,预读 0 次。

select top 10000 gid,fariqi,reader,title from tgongwen order by fariqi desc

用时:156毫秒。 扫描计数 1,逻辑读 289 次,物理读 0 次,预读 0 次。

从以上咱们可以看出,不排序的速度以及逻辑读次数都是和“order by 调集索引列” 的速度是适当的,但这些都比“order by 非调集索引列”的查询速度是快得多的。

一同,依照某个字段进行排序的时分,无论是正序仍是倒序,速度是根本适当的。

12、高效的TOP
现实上,在查询和提取超大容量的数据集时,影响数据库呼应时刻的最大要素不是数据查找,而是物理的I/0操作。如:

select top 10 * from (

select top 10000 gid,fariqi,title from tgongwen

where neibuyonghu=办公室

order by gid desc) as a

order by gid asc

这条句子,从理论上讲,整条句子的履行时刻应该比子句的履行时刻长,但现实相反。因为,子句履行后回来的是10000条记载,而整条句子仅回来10条句子,所以影响数据库呼应时刻最大的要素是物理I/O操作。而束缚物理I/O操作此处的最有用办法之一就是运用TOP关键词了。TOP关键词是SQL SERVER中通过体系优化过的一个用来提取前几条或前几个百分比数据的词。经笔者在实践中的运用,发现TOP的确很好用,功率也很高。但这个词在别的一个大型数据库ORACLE中却没有,这不能说不是一个惋惜,尽管在ORACLE中可以用其他办法(如:rownumber)来处理。在今后的关于“完结千万级数据的分页显现存储进程”的评论中,咱们就将用到TOP这个关键词。

到此为止,咱们上面评论了怎么完结从大容量的数据库中快速地查询出您所需求的数据办法。当然,咱们介绍的这些办法都是“软”办法,在实践中,咱们还要考虑各种“硬”要素,如:网络功用、服务器的功用、操作体系的功用,乃至网卡、交换机等。

三、完结小数据量和海量数据的通用分页显现存储进程

树立一个web 运用,分页阅读功用必不可少。这个问题是数据库处理中十分常见的问题。经典的数据分页办法是:ADO 纪录集分页法,也就是运用ADO自带的分页功用(运用游标)来完结分页。但这种分页办法仅适用于较小数据量的景象,因为游标自身有缺陷:游标是存放在内存中,很费内存。游标一树立,就将相关的记载锁住,直到撤销游标。游标供给了对特定调集中逐行扫描的手法,一般运用游标来逐行遍历数据,依据取出数据条件的不同进行不同的操作。而关于多表和大表中界说的游标(大的数据调集)循环很简略使程序进入一个绵长的等候乃至死机。

更重要的是,关于十分大的数据模型而言,分页检索时,假如依照传统的每次都加载整个数据源的办法是十分浪费资源的。现在盛行的分页办法一般是检索页面巨细的块区的数据,而非检索一切的数据,然后单步履行其时行。

最早较好地完结这种依据页面巨细和页码来提取数据的办法大约就是“俄罗斯存储进程”。这个存储进程用了游标,因为游标的局限性,所以这个办法并没有得到咱们的遍及认可。

后来,网上有人改造了此存储进程,下面的存储进程就是结合咱们的办公主动化实例写的分页存储进程:

CREATE procedure pagination1

(@pagesize int,  --页面巨细,如每页存储20条记载

@pageindex int  --其时页码

)

as

set nocount on

begin

declare @indextable table(id int identity(1,1),nid int)  --界说表变量

declare @PageLowerBound int  --界说此页的底码

declare @PageUpperBound int  --界说此页的顶码

set @PageLowerBound=(@pageindex-1)*@pagesize

set @PageUpperBound=@PageLowerBound+@pagesize

set rowcount @PageUpperBound

insert into @indextable(nid) select gid from TGongwen where fariqi dateadd(day,-365,getdate()) order by fariqi desc

select O.gid,O.mid,O.title,O.fadanwei,O.fariqi from TGongwen O,@indextable t where O.gid=t.nid

and t.id @PageLowerBound and t.id =@PageUpperBound order by t.id

end

set nocount off

以上存储进程运用了SQL SERVER的最新技能――表变量。应该说这个存储进程也是一个十分优异的分页存储进程。当然,在这个进程中,您也可以把其间的表变量写成暂时表:CREATE TABLE #Temp。但很明显,在SQL SERVER中,用暂时表是没有用表变量快的。所以笔者刚开端运用这个存储进程时,感觉十分的不错,速度也比本来的ADO的好。但后来,我又发现了比此办法更好的办法。

笔者曾在网上看到了一篇小短文《从数据表中取出第n条到第m条的记载的办法》,全文如下:

从publish 表中取出第 n 条到第 m 条的记载:
SELECT TOP m-n+1 *
FROM publish
WHERE (id NOT IN
(SELECT TOP n-1 id
FROM publish))

id 为publish 表的关键字

我其时看到这篇文章的时分,真的是精神为之一振,觉得思路十分得好。比及后来,我在作办公主动化体系(ASP.NET+ C#+SQL SERVER)的时分,遽然想起了这篇文章,我想假如把这个句子改造一下,这就或许是一个十分好的分页存储进程。所以我就满网上找这篇文章,没想到,文章还没找到,却找到了一篇依据此句子写的一个分页存储进程,这个存储进程也是现在较为盛行的一种分页存储进程,我很懊悔没有争先把这段文字改形成存储进程:

CREATE PROCEDURE pagination2
(
@SQL nVARCHAR(4000),  --不带排序句子的SQL句子
@Page int,  --页码
@RecsPerPage int,  --每页包容的记载数
@ID VARCHAR(255),  --需求排序的不重复的ID号
@Sort VARCHAR(255)  --排序字段及规矩
)
AS

DECLARE @Str nVARCHAR(4000)

SET @Str=SELECT  TOP +CAST(@RecsPerPage AS VARCHAR(20))+ * FROM (+@SQL+) T WHERE T.+@ID+NOT IN
(SELECT  TOP +CAST((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+ +@ID+ FROM (+@SQL+) T9 ORDER BY +@Sort+) ORDER BY +@Sort

PRINT @Str

EXEC sp_ExecuteSql @Str
GO

其实,以上句子可以简化为:

SELECT TOP 页巨细 *

FROM Table1

WHERE (ID NOT IN

  (SELECT TOP 页巨细*页数 id

  FROM 表

  ORDER BY id))

ORDER BY ID

但这个存储进程有一个丧命的缺陷,就是它含有NOT IN字样。尽管我可以把它改造为:

SELECT TOP 页巨细 *

FROM Table1

WHERE not exists

(select * from (select top (页巨细*页数) * from table1 order by id) b where b.id=a.id )

order by id

即,用not exists来代替not in,但咱们前面现已谈过了,二者的履行功率实际上是没有差异的。

既便如此,用TOP 结合NOT IN的这个办法仍是比用游标要来得快一些。

尽管用not exists并不能抢救上个存储进程的功率,但运用SQL SERVER中的TOP关键字却是一个十分正确的选择。因为分页优化的终究意图就是防止发生过大的记载集,而咱们在前面也现已提到了TOP的优势,通过TOP 即可完结对数据量的操控。

在分页算法中,影响咱们查询速度的关键要素有两点:TOP和NOT IN。TOP可以进步咱们的查询速度,而NOT IN会减慢咱们的查询速度,所以要进步咱们整个分页算法的速度,就要完全改造NOT IN,同其他办法来代替它。

咱们知道,简直任何字段,咱们都可以通过max(字段)或min(字段)来提取某个字段中的最大或最小值,所以假如这个字段不重复,那么就可以运用这些不重复的字段的max或min作为分水岭,使其成为分页算法中分隔每页的参照物。在这儿,咱们可以用操作符“ ”或“ ”号来完结这个任务,使查询句子契合SARG方式。如:

Select top 10 * from table1 where id 200

所以就有了如下分页计划:

select top 页巨细 *

from table1

where id

  (select max (id) from

  (select top ((页码-1)*页巨细) id from table1 order by id) as T

  ) 

  order by id

在选择即不重复值,又简略分辩巨细的列时,咱们通常会选择主键。下表列出了笔者用有着1000万数据的办公主动化体系中的表,在以GID(GID是主键,但并不是调集索引。)为排序列、提取gid,fariqi,title字段,别离以第1、10、100、500、1000、1万、10万、25万、50万页为例,测验以上三种分页计划的履行速度:(单位:毫秒)

页  码
计划1
计划2
计划3

1
60
30
76

10
46
16
63

100
1076
720
130

500
540
12943
83

1000
17110
470
250

1万
24796
4500
140

10万
38326
42283
1553

25万
28140
128720
2330

50万
121686
127846
7168


从上表中,咱们可以看出,三种存储进程在履行100页以下的分页指令时,都是可以信赖的,速度都很好。但第一种计划在履行分页1000页以上后,速度就降了下来。第二种计划大约是在履行分页1万页以上后速度开端降了下来。而第三种计划却一直没有大的降势,潜力依然很足。

在断定了第三种分页计划后,咱们可以据此写一个存储进程。咱们知道SQL SERVER的存储进程是事前编译好的SQL句子,它的履行功率要比通过WEB页面传来的SQL句子的履行功率要高。下面的存储进程不只含有分页计划,还会依据页面传来的参数来断定是否进行数据总数计算。

-- 获取指定页的数据

CREATE PROCEDURE pagination3

@tblName  varchar(255),  -- 表名

@strGetFields varchar(1000) = *,  -- 需求回来的列

@fldName varchar(255)=,  -- 排序的字段名

@PageSize  int = 10,  -- 页尺度

@PageIndex  int = 1,  -- 页码

@doCount  bit = 0,  -- 回来记载总数, 非 0 值则回来

@OrderType bit = 0,  -- 设置排序类型, 非 0 值则降序

@strWhere  varchar(1500) =   -- 查询条件 (留意: 不要加 where)

AS

declare @strSQL  varchar(5000)  -- 主句子

declare @strTmp  varchar(110)  -- 暂时变量

declare @strOrder varchar(400)  -- 排序类型



if @doCount != 0

  begin

  if @strWhere !=

  set @strSQL = "select count(*) as Total from [" + @tblName + "] where "+@strWhere

  else

  set @strSQL = "select count(*) as Total from [" + @tblName + "]"

end

--以上代码的意思是假如@doCount传递过来的不是0,就履行总数计算。以下的一切代码都是@doCount为0的状况

else

begin



if @OrderType != 0

begin

  set @strTmp = " (select min"

set @strOrder = " order by [" + @fldName +"] desc"

--假如@OrderType不是0,就履行降序,这句很重要!

end

else

begin

  set @strTmp = " (select max"

  set @strOrder = " order by [" + @fldName +"] asc"

end



if @PageIndex = 1

begin

  if @strWhere !=  

  set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ "  from [" + @tblName + "] where " + @strWhere + " " + @strOrder

  else

  set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ "  from ["+ @tblName + "] "+ @strOrder

--假如是第一页就履行以上代码,这样会加速履行速度

end

else

begin

--以下代码赋予了@strSQL以真实履行的SQL代码

set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ "  from ["

  + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["+ @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"+ @strOrder



if @strWhere !=

  set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ "  from ["

  + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["

  + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["

  + @fldName + "] from [" + @tblName + "] where " + @strWhere + " "

  + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder

end

end 

exec (@strSQL)

GO

上面的这个存储进程是一个通用的存储进程,其注释已写在其间了。

在大数据量的状况下,特别是在查询最终几页的时分,查询时刻一般不会超越9秒;而用其他存储进程,在实践中就会导致超时,所以这个存储进程十分适用于大容量数据库的查询。

笔者期望可以通过对以上存储进程的解析,能给咱们带来必定的启示,并给作业带来必定的功率进步,一同期望同行提出更优异的实时数据分页算法。

四、调集索引的重要性和怎么选择调集索引

在上一节的标题中,笔者写的是:完结小数据量和海量数据的通用分页显现存储进程。这是因为在将本存储进程运用于“办公主动化”体系的实践中时,笔者发现这第三种存储进程在小数据量的状况下,有如下现象:

1、分页速度一般维持在1秒和3秒之间。

2、在查询最终一页时,速度一般为5秒至8秒,哪怕分页总数只要3页或30万页。

尽管在超大容量状况下,这个分页的完结进程是很快的,但在分前几页时,这个1-3秒的速度比起第一种乃至没有通过优化的分页办法速度还要慢,借用户的话说就是“还没有ACCESS数据库速度快”,这个知道足以导致用户抛弃运用您开发的体系。

笔者就此剖析了一下,本来发生这种现象的症结是如此的简略,但又如此的重要:排序的字段不是调集索引!

本篇文章的标题是:“查询优化及分页算法计划”。笔者只所以把“查询优化”和“分页算法”这两个联络不是很大的论题放在一同,就是因为二者都需求一个十分重要的东西――调集索引。

在前面的评论中咱们现已提到了,调集索引有两个最大的优势:

1、以最快的速度缩小查询规模。

2、以最快的速度进行字段排序。

第1条多用在查询优化时,而第2条多用在进行分页时的数据排序。

而调集索引在每个表内又只能树立一个,这使得调集索引显得愈加的重要。调集索引的选择可以说是完结“查询优化”和“高效分页”的最关键要素。

但要既使调集索引列既契合查询列的需求,又契合排序列的需求,这通常是一个对立。

笔者前面“索引”的评论中,将fariqi,即用户发文日期作为了调集索引的开始列,日期的准确度为“日”。这种作法的长处,前面现已提到了,在进行划时刻段的快速查询中,比用ID主键列有很大的优势。

但在分页时,因为这个调集索引列存在着重复记载,所以无法运用max或min来最为分页的参照物,进而无法完结更为高效的排序。而假如将ID主键列作为调集索引,那么调集索引除了用以排序之外,没有任何用途,实际上是浪费了调集索引这个名贵的资源。

为处理这个对立,笔者后来又添加了一个日期列,其默认值为getdate()。用户在写入记载时,这个列主动写入其时的时刻,时刻准确到毫秒。即便这样,为了防止或许性很小的重合,还要在此列上创立UNIQUE束缚。将此日期列作为调集索引列。

有了这个时刻型调集索引列之后,用户就既可以用这个列查找用户在刺进数据时的某个时刻段的查询,又可以作为仅有列来完结max或min,成为分页算法的参照物。

通过这样的优化,笔者发现,无论是大数据量的状况下仍是小数据量的状况下,分页速度一般都是几十毫秒,乃至0毫秒。而用日期段缩小规模的查询速度比本来也没有任何愚钝。

调集索引是如此的重要和宝贵,所以笔者总结了一下,必定要将调集索引树立在:

1、您最频频运用的、用以缩小查询规模的字段上;

2、您最频频运用的、需求排序的字段上。

结束语:

本篇文章汇集了笔者近段在运用数据库方面的心得,是在做“办公主动化”体系时实践经历的堆集。期望这篇文章不只可以给咱们的作业带来必定的协助,也期望能让咱们可以体会到剖析问题的办法;最重要的是,期望这篇文章可以抛砖引玉,掀起咱们的学习和评论的爱好,以一起促进,一起为公安科技强警工作和金盾工程做出自己最大的尽力。

最终需求阐明的是,在实验中,我发现用户在进行大数据量查询的时分,对数据库速度影响最大的不是内存巨细,而是CPU。在我的P4 2.4机器上实验的时分,检查“资源管理器”,CPU经常出现继续到100%的现象,而内存用量却并没有改动或许说没有大的改动。即便在咱们的HP ML 350 G3服务器上实验时,CPU峰值也能到达90%,一般继续在70%左右。
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表威尼斯人立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章