谈谈SQL 语句的优化技术

在SQL server 的性能优化过程中,TSQL的语句优化是很重要的一环。当您使用各种手段找出系统最需要优化的语句后,应该如何对该语句进行优化呢?下面列出一些TSQL 语句优化的常见技巧。

1.     语句的执行计划分析

首先要对该语句的执行计划(execution plan)进行分析,找出语句运行慢的原因。比如说,

<>在检查执行计划是否包含table scan /index scan等昂贵的操作?

<>对table, worktable是否进行了大量的逻辑读?

<>是否使用了不合适的join类型?

<>并发(串行)执行计划是否不合适 等等

举一个的例子,

Table ‘myTable‘. Scan count 1, logical reads 15877, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:

CPU time = 47 ms,  elapsed time = 174 ms.

Rows   Executes  StmtText

------ --------- ----------------------------------------------------------------------------------------------

10     1         select EmpNo, Code, MAX(DueDate) from myTable where EmpNo = ‘21250‘   group by EmpNo,Code

10     1           |--Stream Aggregate(GROUP BY:([myTable].[Code]) DEFINE:([Expr1002]=MAX([CERTIFICAT

10     1                |--Sort(ORDER BY:([myTable].[Code] ASC))

10     1                     |--Table Scan(OBJECT:([SSS].[dbo].[myTable]), WHERE:([myTable]

大家看上图,logical reads15877,很大的一个值。 执行计划里面有table Scan,那么明显就是一个缺少index导致表被全扫描的例子。加一个索引就会好了。

再看另外一个例子:

表 ‘myTableStatus‘。扫描计数 0,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次

表 ‘myTable‘。扫描计数 8,逻辑读取 1408666 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次

表 ‘myTableType‘。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

表 ‘Transactions‘。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

Rows                 Executes             StmtText

-------------------- -------------------- -----------------------------------------------------------------------------------

2                    1                    SELECT * FROM  vwmyTableItems WHERE 1=1  AND "myTableTypeId" = 1 AND "BranchId" = 1

2                    1                      |--Sort(DISTINCT ORDER BY:([j].[myTableID] DESC, [j].[UUID] ASC, [j].[ParentID] A

2                    1                           |--Compute Scalar(DEFINE:([Expr1009]=[Log_DB].[dbo].[FormatDate]([Log_DB].[d

2                    1                                |--Nested Loops(Inner Join)

1                    1                                     |--Clustered Index Seek(OBJECT:([Log_DB].[dbo].[Transactions].[PK_

2                    1                                     |--Nested Loops(Inner Join)

1                    1                                          |--Clustered Index Seek(OBJECT:([Log_DB].[dbo].[myTableType].

2                    1                                          |--Nested Loops(Inner Join, OUTER REFERENCES:([j].[myTableSta

0                    0                                               |--Compute Scalar(DEFINE:([Expr1011]=(((substring(replic

2                    1                                               |    |--Nested Loops(Inner Join, OUTER REFERENCES:([PtnI

468971               1                                               |         |--Index Seek(OBJECT:([Log_DB].[dbo].[myTable]

2                    468971                                          |         |--Clustered Index Seek(OBJECT:([Log_DB].[dbo]

2                    2                                               |--Clustered Index Seek(OBJECT:([Log_DB].[dbo].[myTableS

从上面计划看,问题是表myTable逻辑读取 1408666 次,非常巨大。另外Nested Loop的cluster index seek 执行了468971 次. 这样的执行计划导致CPU 很高。 如何减少逻辑读和减少Nested Loop里面的执行次数是关键。 对这类执行计划,可以考虑改写语句,或者尝试不同的join type。比如,使用option(hash join) 来改变join类型,看看性能是否改善。

2.     语句的常见优化手段

分析完毕执行计划,你知道了语句为什么慢。接下来语句的优化常见方法是如下。

<>表/索引 的统计信息是否最新?运行update statistics with FULLSCAN更新统计信息再看看。

<>对有table scan或者index scan的地方,仔细检查是否缺少索引?运行Database tuning wizard对该语句分析下,或者手工加上索引看看。也可以查询sys.dm_db_missing_index_details来看看系统是否大量缺少index。

<>join的类型是否合适,使用join hint试试试用不同的join类型。

<>使用index hint 试下不同的index

<>index是否合适,索引字段的顺序是否最佳?

<> WHERE 语句的写法是否不够有效率?比如说,它是否包含了OR, <>,等符号?

<> 语句里面是否使用了自定义函数UDF?UDF常导致table scan。

<>语句是否导致频繁recompile? 看看是不是temp table导致的。

<> 语句是否返回了大量的结果集合? 返回几万十几万笔资料是有些多哦。可以使用TOP N限制结果集。

<> 是否使用了低效率的游标?尽量使用fast_forward readonly 类型的游标比较好。

<>如果语句开销很大,那么该语句是否有必要?  能否减少它的执行次数?

3.简化和重写语句

在系统的整体性能优化里面, TSQL优化优先级并不是最高的。 下面按照对系统性能影响的重要程度依次列出优化的几个层面:

l  Application

l  Database Design

l  Microsoft SQL Server

l  Operating System

l  Hardware

也就是说,程序的优化效果最明显,接下来是数据库的设计优化,再接下来才是TSQL的优化。硬件的优化是最后考虑比较好。一味增加内存和CPU未必能够解决性能问题。

在程序的优化里面,如果能够改写数据库访问逻辑,改写TSQL语句, 或者简化TSQL语句,有时候你能够获得惊人的性能回报。关于SQL语句的优化技术,可以参考之前的博文:

http://blogs.msdn.com/b/apgcdsd/archive/2011/01/11/sql-1.aspx

http://blogs.msdn.com/b/apgcdsd/archive/2011/01/11/sql-2.aspx

一、引言

一个凸现在很多开发者或数据库管理员面前的问题是数据库系统的性能问题。性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化。本文通过一个例子讲述如何应用简化技术来优化SQL 语句,也讨论在系统设计阶段应该考虑的和语句性能密切相关的一些问题。

如果读者不知道应该优化数据库系统的哪些SQL语句,那么建议读者参考笔者的另外一篇文章,《应用Profiler优化SQL Server数据库系统》。本文不讨论索引,建议读者参考笔者的文章《应用索引技术优化SQL语句》,因为索引技术是优化SQL语句的重要部分。

 

二、简化SQL语句

1.简化的原因

SQL语句越简单越好。语句越复杂,其执行性能就越不可预知。这里先说一下SQL Server 的查询优化器。SQL Server查询优化器是基于成本的优化器。查询优化器分析可能的执行计划并选择一个估计成本最低的计划。对简单的语句而言,查询优化器会很快找到一个高效的执行计划如trivial plan或quick plan来执行语句。这是很理想的。因为对简单的执行计划而言SQL Server几乎不用耗费多少资源在它的生成上面。因为简单的缘故,这样的计划几乎都是最优的执行方式。

对那些复杂语句,其可能有上千个不同的执行计划。在这个情况下,查询优化器不会分析所有可能的组合,而是使用复杂算法找到一个成本与理论上的最小值相当接近的执行计划。语句全面优化是非常耗费资源的。语句越复杂,SQL Server越有可能在寻找最优计划的中途停下来,直接使用已经比较过的较优的一个计划来执行语句。如果寻找最优执行计划的时间和语句执行的时间差不多,那还不如直接执行语句。所以SQL Server产生的执行计划未必就是最优的执行计划。基于查询优化器的这种特性,为了获得稳定的执行性能,SQL语句越简单越好。对复杂的SQL语句,要设法对之进行简化。

2.简化的手段

简化的手段多种多样。在系统规划阶段就必须考虑如何避免复杂查询。一个不好的设计会使你不得不在无数表之间进行多次交叉连接才能得到数据,这大大降低了性能。常见的简化规则如下:

1)不要有超过5个以上的表连接(JOIN)

2)考虑使用临时表或表变量存放中间结果。

3)少用子查询

4)视图嵌套不要过深

连接的表越多,其编译的时间和连接的开销也越大,性能越不好控制。最好是把连接拆开成较小的几个部分逐个顺序执行。优先执行那些能够大量减少结果的连接。拆分的好处不仅仅是减少SQL Server优化的时间,更使得SQL语句能够以你可以预测的方式和顺序执行。SQL Server的查询优化器不是十全十美的。使用这样的简化技术可以避免SQL Server优化器产生不是最优的执行计划。如果一定需要连接很多表才能得到数据,那么很可能意味着设计上的缺陷。

不要有过深的视图嵌套。我就曾经看到有个系统,建立了好多视图,视图里面是复杂的语句,然后在视图的上面再建立视图,系统的视图嵌套有四层之多。我并不是反对使用视图,只是视图越多,语句展开后就越复杂,优化起来就越难。一般视图嵌套不要超过2个为宜。

使用临时表或表变量存放中间结果的目标也是简化SQL语句,使得其执行顺序和执行方式得到控制。这个技术在某些时候会产生戏剧化的效果。

3.简化的例子

可以从分析SQL语句的执行计划开始进行简化。从执行计划中常可以发现非常有价值的信息。充分利用这些信息可以在优化的时候做到事半功倍。让我们看个例子。

我们有如下的SQL语句:

select t1.PID ‘PR Number‘,rsdt ‘Request date‘,per.ename ‘Requestor‘,

ped.ename ‘Deliver to‘,dest ‘Destination‘,  pcat.cdesc ‘Category‘,

‘Claimable‘= Case Claim When ‘1‘ Then ‘Yes‘ else ‘No‘ end,

‘NRE‘= case nre WHEN ‘1‘ THEN ‘Yes‘ else ‘No‘ End,

‘PMCal‘ = case PmCal when ‘1‘ then ‘Yes‘ else ‘No‘ End,

‘Cap Reld‘ = case caprel WHEN ‘1‘ then ‘Yes‘ else ‘No‘ End,

‘Type‘ = Pt.TDesc, ‘Section‘ = PSec.SectDesc,

str(t1.prvalue,15,4) ‘PR  Value‘, d.vndid ‘Vendor Code‘,  t1.status, pes.ename ‘PR is/with‘

from PrMer t1

Left outer join P_view per on per.ecode = t1.reqid  And per.CMpcode = t1.reqidCMpno

Left outer join P_view ped on ped.ecode = t1.dlyid  And ped.CMpcode = t1.dlyidCMpno

Left outer join P_view pes on pes.ecode = t1.status  And pes.CMpcode = t1.statusCMpno

Left outer join PRcg pcat on pcat.catid = t1.catid  And pcat.catidCMpno = t1.catidCMpno

Left outer Join PRte Pt on Pt.Typeid = t1.Type

Left outer Join PRst PSec on PSec.SectPRCode = t1.BuRelated

left outer join PRdtl d on t1.PID = d.PID and t1.CMpno = d.CMpno and d.itmno = ‘1‘

where

( t1.type = ‘1‘)

and

(

t1.reqid = ‘22101‘ and t1.reqidCMpno = ‘P‘

or (

t1.PID in

(  select distinct(PID) from Pra1 where apPID = ‘22101‘ and apPIDCMpno = ‘P‘  )

and ( t1.CMpno in

( select CMpno from Pra1 where apPID = ‘22101‘ and apPIDCMpno = ‘P‘))

)

)

and

t1.PID like ‘%/0%‘

or t1.PID like ‘%/1%‘

or t1.PID like ‘%/2%‘

or t1.PID like ‘%/3%‘

or t1.PID like ‘%/4%‘

or t1.PID like ‘%/5%‘

or t1.PID like ‘%/6%‘

or t1.PID like ‘%/7%‘

or t1.PID like ‘%/8%‘

or t1.PID like ‘%/9%‘

order by t1.PID

Table ‘Pra1‘. Scan count 2, logical reads 13522, physical reads 5, read-ahead reads 13631.

Table ‘Worktable‘. Scan count 178595, logical reads 1114272, physical reads 0, read-ahead reads 0.

Table ‘PrCM‘. Scan count 1, logical reads 2986, physical reads 2, read-ahead reads 2999.

Table ‘Pre2‘. Scan count 3, logical reads 1659, physical reads 13, read-ahead reads 369.

Table ‘Gb_mp‘. Scan count 3, logical reads 5496, physical reads 0, read-ahead reads 1834.

Table ‘Gb_ml‘. Scan count 3, logical reads 81, physical reads 0, read-ahead reads 27.

Table ‘PRcg‘. Scan count 1, logical reads 4, physical reads 2, read-ahead reads 2.

Table ‘PRte‘. Scan count 1, logical reads 2, physical reads 2, read-ahead reads 0.

Table ‘PRst‘. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 1.

Table ‘PRdtl‘. Scan count 1, logical reads 9904, physical reads 3, read-ahead reads 9947.

相应的执行计划(部分)如下:

77       1     |--Filter(WHERE:(((((((((like([t1].[PrId], ‘%/1%‘, NULL) OR like([t1].[PrId], ‘%

89668    1          |--Nested Loops(Left Semi Join, WHERE:(((((((((((like([t1].[PrId], ‘%/1%‘,

89668    1               |--Sort(ORDER BY:([t1].[CompNo] ASC))

89668    1               |    |--Merge Join(Left Semi Join, MANY-TO-MANY MERGE:([t1].[PrId])=([

89668    1               |         |--Filter(WHERE:(((((((((([t1].[Type]=‘1‘ AND like([t1].[PrI

121820   1               |         |    |--Clustered Index Scan(OBJECT:([PR].[dbo].[PrCM].[PK_P

1131725  1               |         |--Clustered Index Scan(OBJECT:([PR].[dbo].[Pra1].[PK_PrApp

89591    89591           |--Row Count Spool

1        1                    |--Filter(WHERE:([Pra1].[ApprIdCompno]=‘P‘))

1        1                         |--Bookmark Lookup(BOOKMARK:([Bmk1025]), OBJECT:([PR].[dbo].

26       1                              |--Index Seek(OBJECT:([PR].[dbo].[Pra1].[idx_PrApprova

先不说执行计划如何。光从语句本身本我发现了以下这些问题:

1)连接JOIN太多,有7个之多,还不包括视图里面可能包含的连接。要设法减少连接的个数。

2)连接是outer join,非常不好。因为outer join意味着必须对左表或右表查询所有行。如果表很大而没有相应的where语句,那么outer join很容易导致table scan或index scan。要尽量使用inner join避免scan整个表。

3)不相关子查询的使用有待斟酌。

4)Like语句使用了前置百分号,而Or子句大大增加了使用scan表的几率。

再看看statistics IO的输出,根据logical reads判断那些是最昂贵的表。一个是Pra1,logical reads 13522,,比较大。另一个是worktable,logical reads是1114272。Logical reads高的表应该优先优化。再来看执行计划。我从计划中发现了如下的问题:

1)那些like语句对应的PID 字段的index果然没有使用,而是在全部数据查询出来后再作Filter,所以这些like完全不能减少IO。

2)使用了Row Count Spool,这导致了worktable大量的logical reads。 SQL Server使用row count spool来存放中间结果,这个spool对应tempdb中的worktable。如果再仔细一点,你会发现,这个spool是因为SQL Server对一个小表进行了89591次nest loop scan所导致的。优化的关键是要避免这么多次的loop scan。

3)有两处使用了clustered index scan。Clustered index scan相当于全表的table scan。

估计是语句的where语句条件不够强或索引不够好所致。

4) 一个最关键的地方是,返回的行数是77行,但logical reads却有上百万。我们前面说过,如果结果行数和statistics IO的输出相差太大,那么意味着某个地方缺少优化。究竟是什么地方呢?是LIKE语句。这是因为只有like语句的那个Filter才大大减少了返回的行数,但是like语句却因为前置百分号而无法使用索引。

根据上面的分析,可以得出如下的优化建议:

1)使用临时表存放t1表的结果,共77行。还记得吗,能大大减少logical reads(或返回行数)的操作要优先执行。所以我们要首先试图得到这77行数据。 仔细分析语句,你会发现where中的条件全是针对表t1的,所以直接使用上面的where子句查询表t1,然后把结果存放再临时表#t1中:

Select t1….. into #tt1 from t1 where…(和上面的where一样)

2)再把#tt1和其他表进行连接:

Select #t1…

Left outer join …

Left outer join…

还记得拆分语句的好处吗?语句现在以我们能够预测的顺序和方式执行了。

3)修改程序,去掉前置百分号。

4)从系统设计的角度修改语句,去掉outer join。

5)考虑组合索引或覆盖索引消除clustered index scan。

上面1和2点建议立即消除了worktable,性能提高了几倍以上,效果非常明显。

三、优化SQL语句的系统设计原则

仅仅简化还是不够。SQL语句的优化在系统的设计阶段就要通盘考虑。系统设计越合理,需要优化或后期返工的地方就越少。系统逻辑流程如果不合理,那么常会导致本来需要一个操作就可以解决的问题却要作好几个操作才能实现,反映在数据库上就是发出过多或过复杂的SQL语句。所以数据库系统设计是系统高性能运行的首要关键。

很多系统开发者更关心功能的实现而不是数据库系统的整体运行性能。相当多的开发者对数据库性能优化技术不是很了解,写出来的SQL语句往往缺乏效率。下面让我们罗列一些在设计阶段就应该考虑的和性能密切相关的一些原则。

1)限制结果集

要尽量减少返回的结果行,包括行数和字段列数。返回的结果越大,意味着相应的SQL语句的logical reads 就越大,对服务器的性能影响就越甚。一个很不好的设计就是返回表的所有数据:

Select * from tablename

即使表很小也会导致并发问题。更坏的情况是,如果表有上百万行的话,那后果将是灾难性的。它不但可能带来极重的磁盘IO,更有可能把数据库缓冲区中的其他缓存数据挤出,使得这些数据下次必须再从磁盘读取。没有索引能够优化没有where子句的语句。在这样的语句运行的时候,大量别的小语句会出现超时或缓慢的现象。一个系统只要有几条这样的大语句不定时运行,你几乎肯定会注意到系统性能的不稳定性。所以,必须设计良好的SQL语句,使得其有where语句或TOP语句来限制结果集大小。它通常应该是这个样子的:

Select col1,col2,……from table1 where colx=… and coly=…

没有where语句,或不能预知where语句会返回多少行,是开发者常忽略的地方。程序测试的时候是没有问题的,因为那个时候表的数据还少,不能暴露性能问题。但随着程序部署到实际环境当中,表数据越来越多,问题就会越来越突出。一个稳定优秀的系统应该能够考虑到数据的增长而预知SQL语句会返回多少数据,进而作相应的处理。如果你实在不能知道SQL语句会返回多少数据,那么可以使用TOP n来限制结果集,比如:

Select TOP 100 col1,col2,……from table1 where colx=… and coly=…

其中n不要过大。我就看到有系统采用n=20000的做法,似乎n大了点。你得想一想,我的程序确实需要返回这么多的数据吗?程序的使用者会看这么多的数据吗?

如果语句结果确实很多,可以考虑将结果集进行分页。分页是限制结果集的一种有效手段。比如说,先使用TOP n方式返回头100条数据。只有用户点击下一页的时候才再发出查询获取下100行。

2)合理的表设计

在表的设计中,比较关键的问题是如何处理表的历史数据。表数据会越来越大。你一定需要考虑表的数据增长问题。比如预先考虑一天,一个星期,或一个月内表的数据变化。常见的做法是安排作业定时把表的数据导出到别处,使得数据库保持一定的大小,从而获得稳定一致的性能。也有的系统根据时间设计表,比如说根据月份设计表,如2005一月表,2005二月表,2006三月表等。这样做的好处是每个月表的大小基本稳定一致,性能也可以保证。不好的地方是管理复杂些,程序也要设计成能够根据时间访问不同的月份表。

一个非常令人兴奋的消息是SQL Server 2005将支持表分区技术。利用表分区技术可以实现数据表的流动窗口功能。在流动窗口中可以轻易的把历史数据移出,把新的数据加入,从而使表的大小基本保持稳定。

另外,表的设计未必需要非常范式化。有一定的字段冗余可以增加SQL语句的效率,减少JOIN的数目,提高语句的执行速度。

3)OLAP和OLTP模块要分开

OLAP和OLTP类型的语句是截然不同的。前者往往需要扫描整个表做统计分析,索引对这样的语句几乎没有多少用处。索引只能够加快那些如sum,group by之类的聚合运算。因为这个原因,几乎很难对OLAP类型的SQL语句进行优化。而OLTP语句则只需要访问表的很小一部分数据,而且这些数据往往可以从内存缓存中得到。为了避免OLAP 和OLTP语句相互影响,这两类模块需要分开运行在不同服务器上。因为OLAP语句几乎都是读取数据,没有更新和写入操作,所以一个好的经验是配置一台standby 服务器,然后OLAP只访问standby服务器。

常常有客户咨询我说数据库系统一到月底或一个月的某个时段就变得很慢。你猜猜为什么呢?原来月底是系统生成OLAP报表的时候。报表意味着对几乎全部表数据进行扫描统计,服务器负担自然很重,系统当然比平时慢。我听说某些ERP系统生成一个报表需要好几个小时呢。

 

4)使用存储过程

可以考虑使用存储过程封装那些复杂的SQL语句或商业逻辑,这样做有几个好处。一是存储过程的执行计划可以被缓存在内存中较长时间,减少了重新编译的时间。二是存储过程减少了客户端和服务器的繁复交互。三是如果程序发布后需要做某些改变你可以直接修改存储过程而不用修改程序,避免需要重新安装部署程序。

四、结束语

读完本文,你应该知道简化SQL语句的技术以及系统设计要考虑到的一些原则。应用这些技术能够提高数据库系统的整体性能。数据库系统优化是个很大的话题,本文只是罗列一些有用的经验,更多的需要你的实践。

时间: 2024-10-02 06:30:48

谈谈SQL 语句的优化技术的相关文章

SQL语句的优化

一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一.系统优化中一个很重要的方面就是SQL语句的优化.对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性. 在多数情况下,Oracle使用索

SQL语句性能优化--LECCO SQL Expert

SQL语句的优化是将性能低下的SQL语句转换成目的相同的性能优异的SQL语句. 人工智能自动SQL优化就是使用人工智能技术,自动对SQL语句进行重写,从而找到性能最好的等效SQL语句. 数据库性能的优化   一个数据库系统的生命周期可以分成:设计.开发和成品三个阶段.在设计阶段进行数据库性能优化的成本最低,收益最大.在成品阶段进行数据库性能优化的成本最高,收益最小. 数据库的优化通常可以通过对网络.硬件.操作系统.数据库参数和应用程序的优化来进行.最常见的优化手段就是对硬件的升级.根据统计,对网

Oracle数据库的sql语句性能优化

在应用系统开发初期,由于开发数据库数据比较少,对于查询sql语句,复杂试图的编写等体会不出sql语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要问题之一.系统优化中一个很重要的方面就是sql语句的优化.对于海量数据,劣质sql语句和优质sql语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就行,而是要写出高质量的sql语句,提高系统的可用性. Oracle的sql调优第一个复杂的主题,甚至需要长

SQL语句常见优化十大案例

1.慢SQL消耗了70%~90%的数据库CPU资源: 2.SQL语句独立于程序设计逻辑,相对于对程序源代码的优化,对SQL语句的优化在时间成本和风险上的代价都很低:3.SQL语句可以有不同的写法: 下面是我总结的一些SQL常见的优化方法,每个案例都简单易懂,在开发过程中可以作为参考: 1.不使用子查询例:SELECT * FROM t1 WHERE id (SELECT id FROM t2 WHERE name='hechunyang');子查询在MySQL5.5版本里,内部执行计划器是这样执

关于sql语句的优化

最近在做mysql的数据库优化以及对sql语句优化的指导,写了一点文档,这个大家共勉一下! 数据库参数进行优化所获得的性能提升全部加起来只占数据库应用系统性能提升的40%左右,其余60%的系统性能提升全部来自对应用程序的优化.许多优化专家甚至认为对应用程序的优化可以得到80%的系统性能提升.因此可以肯定,通过优化应用程序来对数据库系统进行优化能获得更大的收益. 通常可分为两个方面: SQL语句的优化和数据库性能调优.应用程序对数据库的操作最终要表现为SQL语句对数据库的操作.而数据库性能调优是结

数据库SQL语句性能优化

选择最有效率的表名顺序 ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表. 如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. WHERE子句中的连接顺序 ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WH

sql语句的优化分析

摘自  http://www.cnblogs.com/knowledgesea/p/3686105.html sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况. 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 没有有效的索引视图 表数据过大没有有效的分区设计 数据库设计太2,存在大量的数据冗余 索引列上缺少相应的统计信息,或者统计信息过期 .... 那么我们如何给找出来导致性能慢的的原因呢? 首先你要

【转】sql语句的优化分析

开门见山,问题所在 sql语句性能达不到你的要求,执行效率让你忍无可忍,一般会时下面几种情况. 网速不给力,不稳定. 服务器内存不够,或者SQL 被分配的内存不够. sql语句设计不合理 没有相应的索引,索引不合理 没有有效的索引视图 表数据过大没有有效的分区设计 数据库设计太2,存在大量的数据冗余 索引列上缺少相应的统计信息,或者统计信息过期 .... 那么我们如何给找出来导致性能慢的的原因呢? 首先你要知道是否跟sql语句有关,确保不是机器开不开机,服务器硬件配置太差,没网你说p啊 接着你使

MySql数据库3【优化2】sql语句的优化

1.SELECT语句优化 1).利用LIMIT 1取得唯一行[控制结果集的行数] 有时,当你要查询一张表是,你知道自己只需要看一行.你可能会去的一条十分独特的记录,或者只是刚好检查了任何存在的记录数,他们都满足了你的WHERE子句.在这种情况下,增加一个LIMIT 1会令你的查询更加有效.这样数据库引擎发现只有1后将停止扫描,而不是去扫描整个表或索引. 2).不要使用BY RAND()命令 这是一个令很多新手程序员会掉进去的陷阱.你可能不知不觉中制造了一个可怕的平静.这个陷阱在你是用BY RAN