首页 > 代码库 > 程序性能优化之SQL篇

程序性能优化之SQL篇

         如果说功能是程序的躯体,那么性能就是程序的灵魂。完整的功能可以保证程序的躯体是健全的,而良好的性能才是程序灵魂的象征,本文就程序的性能优化做简单的介绍。

        最近对程序的性能的体会尤为深刻。最近做了一个数据查询和显示的功能,从7张表大概1500条数据中查询25条数据并且显示出来,时间消耗1秒钟。我的计算机参数为:CPU:i5处理器,4G内存。这个执行速度相当的慢,好在我查询的数据量比较小,等待时间不是很多,但是程序性能优化确实刻不容缓。

        仔细分析了程序,发现有很多地方都是需要修改的,我们先从数据库开始。下面先来看一段代码,这个是程序中的SQL语句:

select {0} from ((((({1} inner join {2}) inner join {3}) inner join {4}) inner join {5}) inner join {6}) inner join {7} where {8} ",
                      "lp.CnName as ProjectCityName,t.TaskName,ls.CnName as StageAreaName,tm.TaskName as TaskTemplateName,t.StartTime,t.RealStartTime,t.EndTime,t.RealEndTime,t.Executor,cc.CnName as CorporationName",
                       "[SubjectDB].[WorkPlan].[Task] as t",
                       "[SubjectDB].[WorkPlan].[Plan] as p on t.PlanCode=p.Code",
                       "[SubjectDB].[WorkPlan].[TemplateTask] as tm on t.TemplateTaskCode = tm.Code",
                        "[SubjectDB].[LandObtained].[ProjectCity] as lp on p.ProjectCityCode = lp.CityCode",
                        "[SubjectDB].[LandObtained].[StageArea] as ls on p.StageAreaCode = ls.Code",
                        "[SubjectDB].[LandObtained].[Corporation_ProjectInfo] as lcp on p.ProjectCode  = lcp.ProjectInfoCode",
                        "[SubjectDB].[Common].[Corporation] as cc on lcp.CorporationCode = cc.Code",
                        "t.RealEndTime <= '" + endTime + "'and t.RealStartTime >='" + startTime + "' and t.VersionEndTime is null and p.ProjectCityCode in ('" + strCityCodeIn + "') and t.TaskStatus = '" + taskStatusCode + "' and ( t.TaskName like " + strTaskPointNameIn + ") and t.TemplateTaskCode not in ('" + strTaskPointCodeIn + "')

          分析一下这段代码,使用了6inner join1in1not in,不固定数量的likestrTaskPointNameIn还附加了orlike)。首先,数据查询就很费劲,这里应该如何进行优化呢?数据库的使用在性能上有哪些需要注意的地方呢?

              inner joinleft join right join

         1 inner join (等值连接)返回两个表连接字段相等的记录

         2 left join (左连接)返回左表中的所有记录和右表中连接字段相等的记录

        3  right join (右连接)返回右表中所有记录和左表中连接字段相等的记录

如:

A

ID1

Name1

1

a

2

a

3

a

 

 

B

ID2

Name2

1

b

3

b

4

b

 

Innerjoin :

         select * from A inner join B onA.ID  = B.ID

结果:

ID1

Name1

ID2

Name2

1

a

1

b

3

a

3

b

 

Leftjoin:

Select * from A left join B on A.ID =  B.ID

结果:

ID1

Name1

 ID2

Name2

1

a

1

b

2

a

null

null

3

a

3

b

 

Rightjoin :

Select * from  A right join Bon A .ID  =  B.ID

结果:

ID1

Name1

ID2

Name2

1

a

1

b

3

a

3

b

null

null

4

b

 

       这三种表连接方式,不能直接说那个性能最好,一是看功能需要,二是看具体查询语句。就上面的SQL语句和功能来看,innerjoin应该是最适合的,一是数据量较小,二是不需要多余数据。

  in   Exists

       另一个值得讨论的地方就是inexists的使用了,这两者是在嵌套查询的时候使用的。我们先来看它们各自的查询原理。

        in是把外表和内表做hash连接,exists是把外表做loop循环,每次循环再对内表进行查询,一直以来说existsin的查询方式更快是不准确的,不同情况结果也不一样,并且如果内外表数据量相一致的情况下,两种方式效率是相同的。

        现在,我们还是假设有两个表:

A表:数据量较小,B表:数据量较大。

 select * from A where cc in(select  cc  from B)

         效率较低,因为in连接使用外表Acc列的索引进行loop循环,然后在B表中寻找等值记录。

 

         select *  from A where  exists (select  cc from B where  cc = A.cc)

        效率较高,因为使用了Bcc列的索引

    Not   in   not exists

         如果查询语句使用到了not    in,那么内外两张表都需要全表扫描,没有用到索引,效率较低;not     exists使用到了索引,所以无论哪个表大,not     exists效率较高。

       暂时写到这里吧,下篇文章继续继续性能优化。 

 


程序性能优化之SQL篇