PHP建立MySQL與MySQLi持久化連接(長(zhǎng)連接)區(qū)別
在PHP開發(fā)中,與數(shù)據(jù)庫(kù)的交互是非常常見的操作。MySQL是一種流行的關(guān)系型數(shù)據(jù)庫(kù),而PHP為其提供了兩種不同的API,即MySQL和MySQLi。在使用這兩個(gè)API時(shí),我們可以選擇使用持久連接或非持久連接。MySQL的持久連接需使用`mysql_pconnect`,而MySQLi持久連接默認(rèn)啟用。盡管MySQLi有性能和安全優(yōu)勢(shì),但使用持久連接時(shí)應(yīng)注意服務(wù)器連接限制和資源占用問題。
php-mysql的持久連接只在同一個(gè)進(jìn)程里可“復(fù)用”,不同進(jìn)程之間玩不了。fpm的子進(jìn)程可以常駐,所以只要子進(jìn)程還在,那么上一次請(qǐng)求創(chuàng)建的持久連接,下一次請(qǐng)求還可以復(fù)用。cli每次都新起一個(gè)進(jìn)程,沒法把連接復(fù)用,那么短連接和持久連接其實(shí)是一樣的。
如果在 PHP 5.3 的版本以前想要?jiǎng)?chuàng)建MySQL的持久化連接(長(zhǎng)連接),需要顯式調(diào)用 pconnect 創(chuàng)建:
$con = mysql_pconnect($server['host'], $server['username'], $server['password']); if (!($con === false)) { if (mysql_select_db($server['database'], $con) === false) { echo('Could not select database: ' . mysql_error()); continue; } // do something here…… }
從 PHP 5.3 開始, mysqli 擴(kuò)展開始支持持久化連接,持久化連接已經(jīng)在 PDO MYSQL 和 ext/mysql 中提供支持。
持久化連接的優(yōu)勢(shì)
持久化連接的目的在于重用客戶端到服務(wù)器之間的連接, 而不是每次在需要的時(shí)候都重新建立一個(gè)連接。
由于持久化連接可以將已經(jīng)建立的連接緩存起來,以備后續(xù)的使用, 所以省去了建立新的連接的開銷, 因此可以帶來性能上的提升。
不像 mysql 擴(kuò)展,mysqli 沒有提供一個(gè)特殊的方法用于打開持久化連接。 如果 mysqli 打開一個(gè)持久化連接,需要在創(chuàng)建連接時(shí),在host前面增加p:
兩個(gè)字符。
mysql 和 mysqli 擴(kuò)展的區(qū)別如下:
持久鏈接建立方式,mysqli是在host前面增加“p:”兩個(gè)字符;mysql使用mysql_pconnect函數(shù);
mysqli 建立的持久鏈接,必須在mysqli_close之后,才能被下一個(gè)請(qǐng)求復(fù)用;mysql的長(zhǎng)連接,可以立即被復(fù)用;
pdo 建立的持久鏈接,不必關(guān)閉,就能復(fù)用;
mysqli 建立持久鏈接時(shí),會(huì)自動(dòng)清理上一個(gè)會(huì)話變量、回滾事務(wù)、解鎖表、釋放鎖等操作;而 mysql 擴(kuò)展則不會(huì)(這點(diǎn)非常重要);
mysqli 判斷是否為同一持久鏈接標(biāo)識(shí)是 IP,PORT、USER、PASS、DBNAME、SOCKET;mysql 是 IP、PORT、USER、PASS、CLIENT_FLAGS;
持久化長(zhǎng)連接的風(fēng)險(xiǎn)
使用持久化連接也會(huì)存在一些風(fēng)險(xiǎn), 因?yàn)樵诰彺嬷械倪B接可能處于一種不可預(yù)測(cè)的狀態(tài)。
例如,如果客戶端未能正常關(guān)閉連接, 可能在這個(gè)連接上殘留了對(duì)庫(kù)表的鎖, 那么當(dāng)這個(gè)連接被其他請(qǐng)求重用的時(shí)候,這個(gè)連接還是處于 有鎖的狀態(tài)。
所以,如果要很好的使用持久化連接,那么要求代碼在和數(shù)據(jù)庫(kù)進(jìn)行交互的時(shí)候, 確保做好清理工作,保證被緩存的連接是一個(gè)干凈的,沒有殘留的狀態(tài)。
mysqli 擴(kuò)展的持久化連接提供了內(nèi)建的清理處理代碼。 mysqli 所做的清理工作包括:
回滾處于活動(dòng)狀態(tài)的事務(wù)
關(guān)閉并且刪除臨時(shí)表
對(duì)表解鎖
重置會(huì)話變量
關(guān)閉預(yù)編譯 SQL 語句(在PHP中經(jīng)常發(fā)生)
關(guān)閉處理程序
釋放通過 GET_LOCK() 獲得的鎖
這確保了將連接返回到連接池的時(shí)候, 它處于一種“干凈”的狀態(tài),可以被其他客戶端進(jìn)程所使用。
mysqli 擴(kuò)展 通過自動(dòng)調(diào)用 C-API 函數(shù) mysql_change_user() 來完成這個(gè)清理工作。
自動(dòng)清理的特性有優(yōu)點(diǎn)也有缺點(diǎn):
優(yōu)點(diǎn)是程序員不再需要擔(dān)心附加的清理代碼, 因?yàn)樗鼈儠?huì)自動(dòng)調(diào)用。
然而缺點(diǎn)就是 性能 可能會(huì) 慢一點(diǎn), 因?yàn)槊看螐倪B接池返回一個(gè)連接都需要執(zhí)行這些清理代碼。
這個(gè)自動(dòng)清理的代碼可以通過在編譯 php 時(shí)定義MYSQLI_NO_CHANGE_USER_ON_PCONNECT
來關(guān)閉。
注意: mysqli 擴(kuò)展在使用 MySQL Native Driver 或 Mysql Client Library(libmysql)時(shí)都支持持久化連接。
為什么我的長(zhǎng)連接不生效?
村長(zhǎng)多說兩句,相信很多小伙伴遇到過這個(gè)問題:
明明創(chuàng)建了 pconnect,show process_list 查看數(shù)據(jù)庫(kù)鏈接,卻發(fā)現(xiàn)長(zhǎng)連接沒有被復(fù)用,而是重新創(chuàng)建了一個(gè),這是為啥呢?這得從PHP的運(yùn)作模式說起。
一般 php 有2種運(yùn)行模式, 一是作為 cgi 運(yùn)行, 二是作為 apache 的模塊運(yùn)行:
作為 cgi 的時(shí)候 connect 跟 pconnect 沒什么不同, 因?yàn)槊看?cgi 進(jìn)行運(yùn)行結(jié)束后都會(huì)被銷毀清理掉資源;
php 作為 apache 模塊方式運(yùn)行時(shí), 可以使用到數(shù)據(jù)庫(kù)持續(xù)連接, 但可能會(huì)存在潛在的問題;
說白了,如果你是 cgi 運(yùn)行方式,pconnection 永遠(yuǎn)也不會(huì)生效。
長(zhǎng)連接最大的缺點(diǎn)就是萬一一個(gè)用戶鎖死,當(dāng)前進(jìn)程就永久鎖死了;假如你在apache里的設(shè)置是進(jìn)程永不銷毀的話就…
總之,盡量使用 mysql_connect,因?yàn)檫\(yùn)行結(jié)束后會(huì)自動(dòng)斷開;再說了現(xiàn)在的機(jī)器性能都不差,不至于缺少那點(diǎn)兒創(chuàng)建銷毀帶來的內(nèi)存開銷。
到此這篇關(guān)于PHP建立MySQL與MySQLi持久化連接(長(zhǎng)連接)區(qū)別的文章就介紹到這了,更多相關(guān)php連接MySQL與MySQLi的長(zhǎng)連接區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP時(shí)間類完整實(shí)例(非常實(shí)用)
這篇文章主要介紹了PHP時(shí)間類完整實(shí)例,涉及PHP針對(duì)日期、時(shí)間、星期等的獲取與比較等操作技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-12-12phpexcel導(dǎo)出excel的顏色和網(wǎng)頁中的顏色顯示不一致
關(guān)于phpexcel導(dǎo)出顏色的一些問題,用phpexcel做導(dǎo)出的excel的顏色怎么和網(wǎng)頁中的顏色顯示不一致呢,接下來將詳細(xì)介紹解決方法2012-12-12PHP橋接模式Bridge Pattern的優(yōu)點(diǎn)與實(shí)現(xiàn)過程
這篇文章主要介紹了PHP橋接模式Bridge Pattern的優(yōu)點(diǎn)與實(shí)現(xiàn)過程,橋接模式是一種結(jié)構(gòu)型模式,它將抽象部分與實(shí)現(xiàn)部分分離開來,使它們可以獨(dú)立地變化2023-03-03php mysql_list_dbs()函數(shù)用法示例
這篇文章主要介紹了php mysql_list_dbs()函數(shù)用法,簡(jiǎn)單介紹了mysql_list_dbs()函數(shù)的功能及列出mysql所有數(shù)據(jù)庫(kù)的實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03關(guān)于php 接口問題(php接口主要也就是運(yùn)用curl,curl函數(shù))
本篇文章是對(duì)php中的接口問題(php接口主要也就是運(yùn)用curl,curl函數(shù))進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-07-07php獲取json數(shù)據(jù)所有的節(jié)點(diǎn)路徑
這篇文章主要介紹了php獲取json數(shù)據(jù)所有的節(jié)點(diǎn)路徑的方法和實(shí)例,有需要的小伙伴可以參考下。2015-05-05PHP中file_exists()判斷中文文件名無效的解決方法
這篇文章主要介紹了PHP中file_exists()判斷中文文件名無效的解決方法,是很多PHP開發(fā)人員都會(huì)遇到的問題,主要涉及對(duì)編碼的轉(zhuǎn)換,需要的朋友可以參考下2014-11-11PHP實(shí)現(xiàn)圖的鄰接矩陣表示及幾種簡(jiǎn)單遍歷算法分析
這篇文章主要介紹了PHP實(shí)現(xiàn)圖的鄰接矩陣表示及幾種簡(jiǎn)單遍歷算法,結(jié)合實(shí)例形式分析了php基于鄰接矩陣實(shí)現(xiàn)圖的定義及相關(guān)遍歷操作技巧,需要的朋友可以參考下2017-11-11PHP中file_exists與is_file,is_dir的區(qū)別介紹
很顯然file_exists是受了asp的影響,因?yàn)閍sp不但有fileExists還有folderExists,driverExists,那么PHP中file_exists是什么意思呢2012-09-09