當前位置:首頁 » 存儲配置 » mysql存儲過程效率

mysql存儲過程效率

發布時間: 2022-07-29 22:22:41

A. mysql中使用存儲過程進行查詢效率高嗎

mysql中使用存儲過程進行查詢效率高嗎
能,存儲過程是在伺服器端運行的。 1、執行速度比普通的SQL語句快 再運行存儲過程前,資料庫已對其進行了語法和句法分析,並給出了優化執行方案。這種已經編譯好的過程可極大地改善SQL語句的性能。

B. 關於存mysql存貯過程與sql的效率問題

存儲過程不僅僅是為了方便你少打字而用的。也不僅僅是一個方法那麼簡單。
僅討論效率的話,通常情況下,執行存儲過程所需的SQL語句遠短於直接執行SQL語句。而且存儲過程在資料庫內部會被優化,所以也比直接執行效率更高。

以下是SQL 2K8幫助的說明:
======================================
Microsoft SQL Server 中的存儲過程與其他編程語言中的過程類似,原因是存儲過程可以:

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

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

向調用過程或批處理返回狀態值,以指明成功或失敗(以及失敗的原因)。

可以使用 Transact-SQL EXECUTE 語句來運行存儲過程。存儲過程與函數不同,因為存儲過程不返回取代其名稱的值,也不能直接在表達式中使用。

在 SQL Server 中使用存儲過程而不使用存儲在客戶端計算機本地的 Transact-SQL 程序的好處包括:

存儲過程已在伺服器注冊。

存儲過程具有安全特性(例如許可權)和所有權鏈接,以及可以附加到它們的證書。

用戶可以被授予許可權來執行存儲過程而不必直接對存儲過程中引用的對象具有許可權。

存儲過程可以強制應用程序的安全性。

參數化存儲過程有助於保護應用程序不受 SQL Injection 攻擊。有關詳細信息,請參閱 SQL Injection。

存儲過程允許模塊化程序設計。

存儲過程一旦創建,以後即可在程序中調用任意多次。這可以改進應用程序的可維護性,並允許應用程序統一訪問資料庫。

存儲過程是命名代碼,允許延遲綁定。

這提供了一個用於簡單代碼演變的間接級別。

存儲過程可以減少網路通信流量。

一個需要數百行 Transact-SQL 代碼的操作可以通過一條執行過程代碼的語句來執行,而不需要在網路中發送數百行代碼。

C. 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';

D. MySQL的存儲過程和函數效率不如MSSQL和oracle嗎

這兩家的腳本引擎非常成熟,效率很高,而mysql的連腳本都算不上,所以在存儲過程和函數里只做CRUD,別干別的,干別的話都會拖慢效率。

E. mysql存儲過程的if判斷有多個條件該怎麼優化效率

這個應該不會太慢吧,我建議你看一下,你是不是循環做了太多次的插入/更新操作。
mysql默認的配置中,每次事務提交都要寫binlog和redo log,如果循環太多次——比如循環插入10w條記錄——就會非常慢。一般優化思路分兩種:
1 修改 sync_binlog為一個100-1000間的值,讓binlog每隔100-1000個事務後再寫一次;修改innodb_flush_log_at_trx_commit =2; 這么搞的好處是降低了寫log的次數和消耗的時間,缺點是,中間出錯的話,會丟失一部分的binlog和redolog導致無法通過他們來在出問題是恢復生產庫數據。
2 將所有的插入/更新操作放到一個事務中進行。這樣,顯然就只需要一次寫binlong和redolog咯。

F. mysql 存儲過程的執行速度不快

大致看了下,用了2個游標,2個臨時表,n個insert、update操作。。。
游標是不推薦使用的,慢,如果真得用,那還是放到後台php去循環好。
主要是沒弄懂你要做的操作和邏輯,不然mysql用join來操作,把游標去掉,換成mysql自己每行去遍歷,估計也就毫秒級。(估計你目前整個表的數據也就幾萬而已)

G. mysql 存儲過程執行太慢怎麼優化

1.當我們請求mysql伺服器的時候,MySQL前端會有一個監聽,請求到了之後,伺服器得到相關的SQL語句,執行之前(虛線部分為執行),還會做許可權的判斷
2.通過許可權之後,SQL就到MySQL內部,他會在查詢緩存中,看該SQL有沒有執行過,如果有查詢過,則把緩存結果返回,說明在MySQL內部,也有一個查詢緩存.但是這個查詢緩存,默認是不開啟的,這個查詢緩存,和我們的Hibernate,Mybatis的查詢緩存是一樣的,因為查詢緩存要求SQL和參數都要一樣,所以這個命中率是非常低的(沒什麼卵用的意思)。
3.如果我們沒有開啟查詢緩存,或者緩存中沒有找到對應的結果,那麼就到了解析器,解析器主要對SQL語法進行解析
4.解析結束後就變成一顆解析樹,這個解析樹其實在Hibernate裡面也是有的,大家回憶一下,在以前做過Hibernate項目的時候,是不是有個一個antlr.jar。這個就是專門做語法解析的工具.因為在Hibernate裡面有HQL,它就是通過這個工具轉換成SQL的,我們編程語言之所以有很多規范、語法,其實就是為了便於這個解析器解析,這個學過編譯原理的應該知道.
5.得到解析樹之後,不能馬上執行,這還需要對這棵樹進行預處理,也就是說,這棵樹,我沒有經過任何優化的樹,預處理器會這這棵樹進行一些預處理,比如常量放在什麼地方,如果有計算的東西,把計算的結果算出來等等...
6.預處理完畢之後,此時得到一棵比較規范的樹,這棵樹就是要拿去馬上做執行的樹,比起之前的那棵樹,這棵得到了一些優化
7.查詢優化器,是MySQL裡面最關鍵的東西,我們寫任何一條SQL,比如SELECT * FROM USER WHERE USERNAME = toby AND PASSWORD = 1,它會怎麼去執行?它是先執行username = toby還是password = 1?每一條SQL的執行順序查詢優化器就是根據MySQL對數據統計表的一些信息,比如索引,比如表一共有多少數據,MySQL都是有緩存起來的,在真正執行SQL之前,他會根據自己的這些數據,進行一個綜合的判定,判斷這一次在多種執行方式裡面,到底選哪一種執行方式,可能運行的最快.這一步是MySQL性能中,最關鍵的核心點,也是我們的優化原則.我們平時所講的優化SQL,其實說白了,就是想讓查詢優化器,按照我們的想法,幫我們選擇最優的執行方案,因為我們比MySQL更懂我們的數據.MySQL看數據,僅僅只是自己收集到的信息,這些信息可能是不準確的,MySQL根據這些信息選了一個它自認為最優的方案,但是這個方案可能和我們想像的不一樣.
8.這里的查詢執行計劃,也就是MySQL查詢中的執行計劃,比如要先執行username = toby還是password = 1
9.這個執行計劃會傳給查詢執行引擎,執行引擎選擇存儲引擎來執行這一份傳過來的計劃,到磁碟中的文件中去查詢,這個時候重點來了,影響這個查詢性能最根本的原因是什麼?就是硬碟的機械運動,也就是我們平時熟悉的IO,所以一條查詢語句是快還是慢,就是根據這個時間的IO來確定的.那怎麼執行IO又是什麼來確定的?就是傳過來的這一份執行計劃.(優化就是制定一個我們認為最快的執行方案,最節省IO,和執行最快)
10.如果開了查詢緩存,則返回結果給客戶端,並且查詢緩存也放一份。

H. 用mysql資料庫的存儲過程使用游標效率低下怎麼解決

不知道你 什麼版本的 mysql
1、
我使用的 mysql, 好像沒有 create or replace procere 這樣的語法。
只能 create procere
可能是我的 mysql 版本太低了吧...

2、
MySQL 存儲過程名字後面的「()」是必須的,即使沒有一個參數,也需要「()」

這個不知道是不是也是我mysql 版本太低的問題。

create or replace procere proc_updateDist

修改為
create procere proc_updateDist ()

3、游標部分, 缺少了 DECLARE CONTINUE HANDLER
以及 判斷什麼時候退出循環的語句。

I. mysql 存儲過程中 用臨時表 性能消耗大嗎

1、首選在編譯安裝MySQL的時候指定兩個參數使用utf8編碼。
2、次選在配置文件my.cnf或my.ini設定兩個參數,同時設置init_connect參數。
3、第三在配置文件my.cnf或my.ini設定兩個參數,同時客戶端的連接指定set names命令。
4、在配置文件my.cnf里的client和server處加入default-character-set參數方便管理。

J. mysql 是否推薦使用存儲過程mysql的存儲過程能帶來什麼優勢以及有什麼缺點呢一般適用於什麼情況

優勢就是提前編譯好了的存儲過程,少了些分析和解釋的過程提高效率,缺點就是不靈活,只能進行傳入一些固定的參數進行流程化的運行。適用於接收幾個參數進行多次資源操作的情況。

熱點內容
21款昂科威哪個配置好 發布:2024-10-06 02:20:39 瀏覽:835
拆裝空調壓縮機 發布:2024-10-06 01:59:47 瀏覽:419
dl演算法 發布:2024-10-06 01:59:44 瀏覽:845
寵物商店java 發布:2024-10-06 01:59:43 瀏覽:536
androidimageview文字 發布:2024-10-06 01:53:55 瀏覽:819
檢查電腦與伺服器的連通性和路徑 發布:2024-10-06 01:37:38 瀏覽:432
宋春麗訪問 發布:2024-10-06 01:34:23 瀏覽:677
美國往事ftp 發布:2024-10-06 01:29:03 瀏覽:772
dtu編程 發布:2024-10-06 01:23:30 瀏覽:595
照片視頻加密 發布:2024-10-05 23:58:58 瀏覽:480