當前位置:首頁 » 服務存儲 » 存儲過程優化
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

存儲過程優化

發布時間: 2022-02-25 04:11:48

⑴ oracle資料庫存儲過程執行慢時如何優化

1 首先看看,先分析慢的原因,一部分是因為循環次數多,一部分是因為查詢數據量大慢。
2 可以從優化查詢入手,比如某次查詢的sql裡面的數據,條件欄位沒有建索引,導致了全表掃描,
是不是 只需要幾個欄位,但是你寫了 select * 等等,總之要優化數據的速度。
2 可以從循環邏輯看起,有些循環可能是不必要的,能不能通過條件查詢來替代循環,總之要從邏輯上優化代碼

⑵ 優化存儲過程

在使用 Microsoft® SQL Server™ 2000 創建應用程序時,Transact-SQL 編程語言是應用程序和 SQL Server 資料庫之間的主要編程介面。使用 Transact-SQL 程序時,可用兩種方法存儲和執行程序。可以在本地存儲程序,並創建向 SQL Server 發送命令並處理結果的應用程序;也可以將程序在 SQL Server 中存儲為存儲過程,並創建執行存儲過程並處理結果的應用程序。

SQL Server 中的存儲過程與其它編程語言中的過程類似,原因是存儲過程可以:

接受輸入參數並以輸出參數的形式將多個值返回至調用過程或批處理。

包含執行資料庫操作(包括調用其它過程)的編程語句。

向調用過程或批處理返回狀態值,以表明成功或失敗(以及失敗原因)。
可使用 Transact-SQL EXECUTE 語句運行存儲過程。存儲過程與函數不同,因為存儲過程不返回取代其名稱的值,也不能直接用在表達式中。

使用 SQL Server 中的存儲過程而不使用存儲在客戶計算機本地的 Transact-SQL 程序的優勢有:

允許模塊化程序設計。
只需創建過程一次並將其存儲在資料庫中,以後即可在程序中調用該過程任意次。存儲過程可由在資料庫編程方面有專長的人員創建,並可獨立於程序源代碼而單獨修改。

允許更快執行。
如果某操作需要大量 Transact-SQL 代碼或需重復執行,存儲過程將比 Transact-SQL 批代碼的執行要快。將在創建存儲過程時對其進行分析和優化,並可在首次執行該過程後使用該過程的內存中版本。每次運行 Transact-SQL 語句時,都要從客戶端重復發送,並且在 SQL Server 每次執行這些語句時,都要對其進行編譯和優化。

減少網路流量。
一個需要數百行 Transact-SQL 代碼的操作由一條執行過程代碼的單獨語句就可實現,而不需要在網路中發送數百行代碼。

可作為安全機制使用。
即使對於沒有直接執行存儲過程中語句的許可權的用戶,也可授予他們執行該存儲過程的許可權。

SQL Server 存儲過程是用 Transact-SQL 語句 CREATE PROCEDURE 創建的,並可用 ALTER PROCEDURE 語句進行修改。存儲過程定義包含兩個主要組成部分:過程名稱及其參數的說明,以及過程的主體(其中包含執行過程操作的 Transact-SQL 語句)。

⑶ SQL存儲過程優化

如何獲取執行計劃

1 把存儲過程放在查詢分析器中,先採用執行計劃自動優化一下,看看是否缺少索引

2 減少存儲過程中的循環操作

⑷ sql存儲過程優化問題

發個看看下,我試一試,

⑸ 怎樣編寫SQL優化語句使存儲過程查詢的更快

1.存儲過程的能增強SQL語言的功能和靈活性。存儲過程可以用流控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算;
2.在運行存儲過程前,資料庫已對其進行了語法和句法分析,並給出了優化執行方案。這種已經編譯好的過程可極大地改善SQL語句的性能。
以上說明了一些存儲過程的好處,但是這不意味這什麼地方都適合用,能用一條select語句查詢出的結果寫成存儲過程只能降低效率,這樣是沒有好處的。要在批量操作,邏輯復雜的業務中使用存儲過程。不能濫用。

⑹ mysql 存儲過程怎麼進行性能優化

在資料庫的開發過程中,經常會遇到復雜的業務邏輯和對資料庫的操作,這個時候就會用存儲過程來封裝資料庫操作。如果項目的存儲過程較多,書寫又沒有一定的規范,將會影響以後的系統維護困難和大存儲過程邏輯的難以理解,另外如果資料庫的數據量大或者項目對存儲過程的性能要求很,就會遇到優化的問題,否則速度有可能很慢,經過親身經驗,一個經過優化過的存儲過程要比一個性能差的存儲過程的效率甚至高幾百倍。下面介紹某一個MySQL存儲過程優化的整個過程。
在本文中,需要被優化的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30)
)
pr_dealtestnum_label:begin

insert into tb_testnum select boxnumber,usertype from tb_testnum_tmp where boxnumber= p_boxnumber;

leave pr_dealtestnum_label;
end;
//
delimiter ;
select 'create procere pr_dealtestnumok';
在存儲過程中使用到的表tb_testnum結構如下:
drop table if exists tb_testnum;

create table tb_testnum
(
boxnumber varchar(30) not null,
usertype int not null
);
create unique index idx1_tb_testnum ontb_testnum(boxnumber);
在存儲過程中使用到的另外一張表tb_testnum_tmp結構如下:
drop table if exists tb_testnum_tmp;

create table tb_testnum_tmp
(
boxnumber varchar(30) not null,
usertype int not null
);
create unique index idx1_tb_testnum_tmp ontb_testnum_tmp(boxnumber);
從兩個表的結構可以看出,tb_testnum和tb_testnum_tmp所包含的欄位完全相同,存儲過程pr_dealtestnum的作用是根據輸入參數將tb_testnum_tmp表的數據插入到tb_testnum表中。
很明顯,雖然能夠實現預期的功能,但存儲過程pr_dealtestnum的代碼還有改進的地方。
下面,我們一步一步來對其進行優化。
優化一
存儲過程pr_dealtestnum的主體是一條insert語句,但這條insert語句裡面又包含了select語句,這樣的編寫是不規范的。因此,我們要把這條insert語句拆分成兩條語句,即先把數據從tb_testnum_tmp表中查找出來,再插入到tb_testnum表中。修改之後的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30)
)
pr_dealtestnum_label:begin
declare p_usertype int;

select usertype into p_usertype from tb_testnum_tmp where boxnumber=p_boxnumber;

insert into tb_testnum values(p_boxnumber,p_usertype);

leave pr_dealtestnum_label;
end;
//
delimiter ;
select 'create procere pr_dealtestnum ok';
優化二
在向tb_testnum表插入數據之前,要判斷該條數據在表中是否已經存在了,如果存在,則不再插入數據。同理,在從tb_testnum_tmp表中查詢數據之前,要先判斷該條數據在表中是否存在,如果存在,才能從表中查找數據。修改之後的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30)
)
pr_dealtestnum_label:begin
declare p_usertype int;
declare p_datacount int;

select count(*) into p_datacount from tb_testnum_tmp where boxnumber=p_boxnumber;
if p_datacount > 0 then
begin
select usertype into p_usertype fromtb_testnum_tmp where boxnumber=p_boxnumber;
end;
else
begin
leave pr_dealtestnum_label;
end;
end if;

select count(*) into p_datacount from tb_testnum where boxnumber=p_boxnumber;
if p_datacount = 0 then
begin
insert into tb_testnum values(p_boxnumber,p_usertype);
leave pr_dealtestnum_label;
end;
else
begin
leave pr_dealtestnum_label;
end;
end if;
end;
//
delimiter ;
select 'create procere pr_dealtestnum ok';
優化三
不管向tb_testnum表插入數據的操作執行成功與否,都應該有一個標識值來表示執行的結果,這樣也方便開發人員對程序流程的追蹤和調試。也就是說,在每條leave語句之前,都應該有一個返回值,我們為此定義一個輸出參數。修改之後的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30),
out p_result int -- 0-succ, other-fail
)
pr_dealtestnum_label:begin
declare p_usertype int;
declare p_datacount int;

select count(*) into p_datacount from tb_testnum_tmp where boxnumber=p_boxnumber;
if p_datacount > 0 then
begin
select usertype into p_usertype from tb_testnum_tmp where boxnumber=p_boxnumber;
end;
else
begin
set p_result = 1;
leave pr_dealtestnum_label;
end;
end if;

select count(*) into p_datacount from tb_testnum where boxnumber=p_boxnumber;
if p_datacount = 0 then
begin
insert into tb_testnum values(p_boxnumber,p_usertype);
set p_result = 0;
leave pr_dealtestnum_label;
end;
else
begin
set p_result = 2;
leave pr_dealtestnum_label;
end;
end if;
end;
//
delimiter ;
select 'create procere pr_dealtestnum ok';
優化四
我們注意到「insert into tb_testnum values(p_boxnumber,p_usertype);」語句中,tb_testnum表之後沒有列出具體的欄位名,這個也是不規范的。如果在以後的軟體版本中,tb_testnum表中新增了欄位,那麼這條insert語句極有可能會報錯。因此,規范的寫法是無論tb_testnum表中有多少欄位,在執行insert操作時,都要列出具體的欄位名。修改之後的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30),
out p_result int -- 0-succ, other-fail
)
pr_dealtestnum_label:begin
declare p_usertype int;
declare p_datacount int;

select count(*) into p_datacount from tb_testnum_tmp where boxnumber=p_boxnumber;
if p_datacount > 0 then
begin
select usertype into p_usertype from tb_testnum_tmp where boxnumber=p_boxnumber;
end;
else
begin
set p_result = 1;
leave pr_dealtestnum_label;
end;
end if;

select count(*) into p_datacount from tb_testnum where boxnumber=p_boxnumber;
if p_datacount = 0 then
begin
insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype);
set p_result = 0;
leave pr_dealtestnum_label;
end;
else
begin
set p_result = 2;
leave pr_dealtestnum_label;
end;
end if;
end;
//
delimiter ;
select 'create procere pr_dealtestnum ok';
優化五
在執行insert語句之後,要用MySQL中自帶的@error_count參數來判斷插入數據是否成功,方便開發人員跟蹤執行結果。如果該參數的值不為0,表示插入失敗,那麼我們就用一個返回參數值來表示操作失敗。修改之後的存儲過程如下:
drop procere if exists pr_dealtestnum;
delimiter //

create procere pr_dealtestnum
(
in p_boxnumber varchar(30),
out p_result int -- 0-succ, other-fail
)
pr_dealtestnum_label:begin
declare p_usertype int;
declare p_datacount int;

select count(*) into p_datacount from tb_testnum_tmp where boxnumber=p_boxnumber;
if p_datacount> 0 then
begin
select usertype into p_usertype from tb_testnum_tmp where boxnumber=p_boxnumber;
end;
else
begin
set p_result = 1;
leave pr_dealtestnum_label;
end;
end if;

select count(*) into p_datacount from tb_testnum where boxnumber=p_boxnumber;
if p_datacount = 0then
begin
insert into tb_testnum(boxnumber,usertype) values(p_boxnumber,p_usertype);
if @error_count<>0 then
begin
set p_result= 3;
end;
else
begin
set p_result= 0;
end;
end if;
end;
else
begin
set p_result = 2;
end;
end if;

leave pr_dealtestnum_label;
end;
//
delimiter ;
select 'create procere pr_dealtestnum ok';

⑺ 這個存儲過程有沒有辦法優化(sql server)

creat proce。。。。。。。。。。
as
select UserID into #a from Users where CompanyName=@companyName

delete from tb_a where UserID in(select * from #a)
delete from tb_b where UserID in(select * from #a)
delete from tb_c where UserID in(select * from #a)
這樣是不是你想要的。

⑻ 存儲過程並發性能優化問題

將多個查詢建立一個視圖,每次訪問這個視圖可以提高性能