SQL文の最適化分析

事態を読むための分析と実行時間の比較計画

選択 *  から dbo.Product

上記のステートメントの実装はどのようにあなたがそれの最適化と最適化後の違いはありません知っています、そして、あなたはそれを分析する方法を、あなたのリターンを与える、といくつかの行を行うことが一般的です。

以下のいくつかの方法:

1.実行時間とCPU使用時間を確認してください

設定され た統計時間を上の
選択 *  からdbo.Product
 設定され た統計時間をオフ

あなたが問い合わせた後見ることができるメッセージを開きます。

2. I / 0のクエリのケースを確認

セット 統計が ioを上の
選択 *  からdbo.Product
 セット 統計は ioをオフ

実行した後

スキャン数:スキャンインデックスまたはテーブルの数

論理読み取り:キャッシュ内のデータのページを読みます

物理読み取り:ページ数は、ディスクから読み取ります

先読み:クエリ処理、キャッシュにディスクからページ数

ロブ論理読み込み:キャッシュ、ページの画像、テキスト、ntext型または大規模データからデータを読み取ります

ロブの物理読み取り:ディスクから読み取る、画像、テキスト、ntext型または大規模データのページ

ディスクイメージ、テキスト、ntext型または大規模なデータから、キャッシュにページの問い合わせ処理を:ロブは先読み

 

物理の読み込み数と先読み倍以上を言うの場合は、インデックスの最適化を使用することができます。

あなたがコンテンツを視聴するには、SQL文のコマンドを使用しますが、また、いくつかの方法でない場合は、弟はあなたが単純に教えます。

クエリ--- --- >>高度なクエリオプション

/オフ効果を試すにSQL文/時間ioのセットの統計情報を削除するには2つの赤い罠に選択されています。まあ、あなたはそれを成功します。

3.実行計画を表示するには、実行計画の詳細

クエリを選択し、クリックして、次の凡例を表示されるメッセージを参照してください

私はこの文の最初の例は単純すぎる、あなたの全体の複合体は、ああ容赦します。

分析:アイコンの上にマウスが来て、下記の各テーブルを再設計データ構造によれば、マルチステーションの割合のコスト分析のパーセンテージを示し、それは書き換えやSQL文は、この手順の実装の詳細が表示されますこの最適化。スキャンテーブルの場合、またはクラスタ化インデックスを行うには、具体的方法を、働いていない場合、あなたは、インデックスの最適化を修正し、改善する必要があり、現在のクエリでは、あなたのインデックスが適切でないことを意味し、存在し、あなたが私に応じてすることができますスキャン前の記事のSQL最適化ツール-データベースエンジンチューニングアドバイザは、インデックスの最適化を分析します。

選択クエリアート

1.それは余分な列と行を照会しませんようにします。

  • 選択の存在を回避するために、*、*代わりに冗長列を避けるために、特定の列を使用します
  • 冗長行を回避するために、データが定義されている特定の用途を見出すこと
  • トップを使用して、個別のキーワードは冗長重複行を減らします

2.明確なキーワードを警告します

個別のクエリの最適化の結果をもたらすために、データの重複を避けるために、クエリフィールドまたはいくつかのフィールドの例で使用されます。

しかし、使用する多くの場合、クエリのフィールドには、それが大幅に検索効率が低下します。

このチャートから、分析:

明らかにCPU時間と経過時間の明確なステートメントを使用していない明確な声明と比べて高くなっています。その理由は、重複データを除外し、あなたは明確なを使用する場合とき、クエリのフィールドの多くは、データベースエンジンは、データを比較することで、しかし、この比較は、濾過プロセスは、システムリソース、CPU時間のいずれかの種類せずに発生します。

3.注意組合キーワード

このキーワードはコレクションに、各クエリの結果の主な機能であり、あなたに結果セットを返します。使い方

<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

 

おすすめ

転載: www.cnblogs.com/zhaoyl9/p/11453883.html