SQL statement optimization analysis

Analysis and comparison of execution time plan to read the situation

select * from dbo.Product

Implementation of the above statement is generally only give you returns, and perform several rows, then how you analyze it, how do you know there is no difference after optimization with the optimization of it.

Several methods below:

1. Check the execution time and cpu usage time

set statistics time on
select * from dbo.Product
set statistics time off

Open a message which you can see after the inquiry

2. Review the query case of I / 0's

set statistics io on
select * from dbo.Product
set statistics io off

After performing

Scan Count: number of scans index or table

Logical reads: read pages of data in the cache

Physical reads: Number of pages read from disk

Pre-reading: query process, the number of pages from disk into cache

lob logical reads: read data from the cache, pages image, text, ntext or large data

lob physical reads: read from the disk, the pages of image, text, ntext or large data

Pages inquiry process into the cache from the disk image, text, ntext or large data: lob read-ahead

 

If the number of physical reads and read-ahead times say more, you can use the index optimization.

If you do not want to use sql statement command to view the content, but also some methods, brother teach you simpler.

Query --- --- >> >> Advanced query options

Is selected on the two red trap to remove set statistics io sql statement / time on / off try the effect. Oh well, you succeed it. .

3. To view the execution plan, the execution plan Detailed

Select the query, click and see the message which will appear the following legend

I first example of this statement is too simple, your whole complex, bear with ah.

Analysis : mouse over the icon will show the details of the implementation of this step, each table below show the percentage of a cost analysis of the percentage of a multi-station, according to re-design data structure, it rewrite or sql statement, to come this optimization. If the scan table, or scan a clustered index exists, which means that in the current query your index is not appropriate, is not worked, then you have to revise and improve the optimization of your index, specifically how to do, you can according to my Previous article sql optimization tool - database engine Tuning advisor to analyze the index optimization.

select query Art

1. To ensure that does not query the extra columns and rows.

  • To avoid the presence of select *, * Instead of using specific column, to avoid redundant column
  • To find particular use where the data is defined, to avoid redundant row
  • Use top, distinct keyword reduce redundant duplicate rows

2. caution distinct keywords

distinct used in the query field or a few field cases, to avoid duplication of data, to bring query optimization results.

But the query field in many cases to use, it will greatly reduce the search efficiency.

From this chart, Analysis:

Obviously with a distinct statement of cpu time and elapsed time are higher than the statement with no distinct. The reason is that when a lot of queries field, if you use distinct, the database engine will compare the data, filter out duplicate data, however this comparison, the filtration process occurs without any kind of system resources, cpu time.

3. caution union keyword

This keyword is the main function of the results of each query to a collection and returns the result set to you. usage

<select 语句1>
union
<select 语句2>
union
<select 语句3>
...

满足union的语句必须满足:1.列数相同。 2.对应列数的数据类型要保持兼容。

执行过程:

依次执行select语句-->>合并结果集--->>对结果集进行排序,过滤重复记录。

select * from 
(( orde o  left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum)  where p.id<10000
union
select * from 
(( orde o  left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum)  where p.id<20000 and p.id>=10000
union
select * from 
(( orde o  left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum)  where p.id>20000   ---这里可以写p.id>100 结果一样,因为他筛选过啦

----------------------------------对比上下两个语句-----------------------------------------
select * from 
(( orde o  left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum) 

 

由此可见效率确实低,所以不是在必要情况下避免使用。其实有他执行的第三部:对结果集进行排序,过滤重复记录。就能看出不是什么好鸟。然而不对结果集排序过滤,显然效率是比union高的,那么不排序过滤的关键字有吗?答,有,他是union all,使用union all能对union进行一定的优化。。

4.判断表中是否存在数据

select count(*) from product 
select top(1) id from product

很显然下面完胜

5.连接查询的优化

首先你要弄明白你想要的数据是什么样子的,然后再做出决定使用哪一种连接,这很重要。

各种连接的取值大小为:

  • 内连接结果集大小取决于左右表满足条件的数量
  • 左连接取决与左表大小,右相反。
  • 完全连接和交叉连接取决与左右两个表的数据总数量
select * from 
( (select * from orde where OrderId>10000) o  left join orderproduct op on o.orderNum=op.orderNum )

select * from 
( orde o left join orderproduct op on o.orderNum=op.orderNum )
 where o.OrderId>10000

由此可见减少连接表的数据数量可以提高效率。

insert插入优化

--创建临时表
create table #tb1
(
 id int,
 name nvarchar(30),
 createTime datetime
)
declare @i int
declare @sql varchar(1000)
set @i=0
while (@i<100000)  --循环插入10w条数据
begin
  set @i=@i+1
  set @sql=' insert into #tb1 values('+convert(varchar(10),@i)+',''erzi'+convert(nvarchar(30),@i)+''','''+convert(nvarchar(30),getdate())+''')'
  exec(@sql)
end

我这里运行时间是51秒

--创建临时表
create table #tb2
(
 id int,
 name nvarchar(30),
 createTime datetime
)

declare @i int
declare @sql varchar(8000)
declare @j int
set @i=0
while (@i<10000)  --循环插入10w条数据
begin 
 set @j=0
 set @sql=' insert into #tb2 select '+convert(varchar(10),@i*100+@j)+',''erzi'+convert(nvarchar(30),@i*100+@j)+''','''+convert(varchar(50),getdate())+''''
 set @i=@i+1
 while(@j<10)
 begin   
   set @sql=@sql+' union all select '+convert(varchar(10),@i*100+@j)+',''erzi'+convert(nvarchar(30),@i*100+@j)+''','''+convert(varchar(50),getdate())+''''
   set @j=@j+1
 end 
 exec(@sql)
end

drop table #tb2
select count(1) from #tb2

我这里运行时间大概是20秒

分析说明:insert into select批量插入,明显提升效率。所以以后尽量避免一个个循环插入。

优化修改删除语句

如果你同时修改或删除过多数据,会造成cpu利用率过高从而影响别人对数据库的访问。

如果你删除或修改过多数据,采用单一循环操作,那么会是效率很低,也就是操作时间过程会很漫长。

这样你该怎么做呢?

折中的办法就是,分批操作数据。

delete product where id<1000
delete product where id>=1000 and id<2000
delete product where id>=2000 and id<3000
.....

当然这样的优化方式不一定是最优的选择,其实这三种方式都是可以的,这要根据你系统的访问热度来定夺,关键你要明白什么样的语句是什么样的效果。

 

 

总结:优化,最重要的是在于你平时设计语句,数据库的习惯,方式。如果你平时不在意,汇总到一块再做优化,你就需要耐心的分析,然而分析的过程就看你的悟性,需求,知识水平啦。

 

 

 原文地址:https://www.cnblogs.com/knowledgesea/p/3686105.html

 

Guess you like

Origin www.cnblogs.com/zhaoyl9/p/11453883.html