連接數(shù)據(jù)庫

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了達(dá)拉特免費建站歡迎大家使用!
代碼如下
?php
$conn = @mysql_connect("localhost","root","root") or die ("database error");
mysql_select_db("DB",$conn);
if (isset($_POST['submit'])){
$num=$_POST['num'];
$sql="SELECT num FROM TEST WHERE num=$num";
$tt=mysql_query($sql,$conn);
$row = mysql_fetch_assoc($tt);
echo "num:".$row['num']."/br";
}
?
在PHP-FPM處理HTTP請求時,有時會遇到一個請求需要進(jìn)行多次MySQL查詢(在報表類應(yīng)用中比較常見)。通常我們會以串行方式查詢:
$link?=?new?mysqli();
$rs1?=?$link-query('SELECT?*?FROM?table1');
while?($row?=?$rs1-fetch_row())?{?...?}
$rs2?=?$link-query('SELECT?*?FROM?table2');
while?($row?=?$rs2-fetch_row())?{?...?}
$rs3?=?$link-query('SELECT?*?FROM?table3');
while?($row?=?$rs3-fetch_row())?{?...?}
串行查詢方式有個缺點:在MySQL返回數(shù)據(jù)之前,PHP一直是處于空等的狀態(tài),不會繼續(xù)往后執(zhí)行。如果數(shù)據(jù)量大或者查詢復(fù)雜,MySQL響應(yīng)可能會比較慢,那么以串行方式查詢會有一些延遲。給用戶最直接的感受就是 Loading… 的圈圈一直打轉(zhuǎn)。
那么有什么辦法可以減少查詢MySQL的時間?用多進(jìn)程并行查詢不行,因為PHP-FPM 中不允許用 pcntl_fork 一類的調(diào)用。
幸好還有 mysqlnd,mysqlnd提供了類似 stream_select 的機制(見 這篇文章) ,可以做到在單進(jìn)程中對MySQL并行查詢。這主要運用了mysqli_poll 和 reap_async_query 兩個函數(shù)。
還是通過例子來介紹MySQL并行查詢的實施方法。假設(shè)要并行地向MySQL發(fā)出10個查詢,最基本的代碼應(yīng)該是這樣的:
1.??$links?=?[];
2.??for?($i?=?0;?$i?!==?10;?$i++)?{
3.??????$links[$i]?=?new?mysqli('127.0.0.1',?'user',?'password',?'db1');
4.??????$links[$i]-query('SELECT?SLEEP(1)',?MYSQLI_ASYNC);
5.??}
6.??$allResult?=?[];
7.??while?(!empty($links))?{
8.??????$reads?=?$links;
9.??????$errors?=?$reject?=?[];
10.?????if?(!mysqli_poll($reads,?$errors,?$reject,?null))?{
11.?????????continue;
12.?????}
13.?????foreach?($reads?as?$read)?{
14.?????????$idx?=?array_search($read,?$links,?true);
15.?????????$allResult[$idx]?=?[];
16.?????????$result?=?$read-reap_async_query();
17.?????????while?($row?=?$result-fetch_row())?{
18.?????????????$allResult[$idx][]?=?$row;
19.?????????}
20.?????????$read-close();
21.?????????unset($links[$idx]);
22.?????}
23.?}
解釋下這段代碼的含義:
2~5行,同時發(fā)起10個MySQL連接,并發(fā)出查詢
注意query() 的第二個參數(shù)帶上了 MYSQLI_ASYNC 表示非阻塞查詢
10行,使用mysqli_poll 輪詢10個連接的查詢有無返回
mysqli_poll 的第一個參數(shù)$reads是個數(shù)組,包含需要輪詢那些連接。mysqli_poll 執(zhí)行完后,會改寫$reads,改寫后$reads包含的是那些已經(jīng)有數(shù)據(jù)返回連接。
mysqli_poll的第四個參數(shù),控制的是輪詢的等待時間,單位是“秒”。如果像本例當(dāng)中設(shè)置為null,那么mysqli_poll輪詢是阻塞的:只有監(jiān)聽的連接中,任意一個連接有數(shù)據(jù)返回了,mysqli_poll才會返回。如果等待時間設(shè)置為0,那么每次執(zhí)行mysqli_poll會立即返回,外層的while會頻繁循環(huán)。
第11~19行,遍歷已經(jīng)有數(shù)據(jù)返回的連接
reap_async_query和普通query一樣,返回的是mysqli_result,可以一行行fetch數(shù)據(jù)
20~21行,對于已經(jīng)獲得了數(shù)據(jù)的連接,下次mysqli_poll就不需要再輪詢這個連接了,所以關(guān)閉連接,并從$links數(shù)組刪除這個連接
當(dāng)所有的連接都返回了數(shù)據(jù),$links數(shù)組空了,while循環(huán)也就終止了。
使用并行查詢的方式,可以大大縮短處理HTTP請求的時間,假設(shè)本例中的10個SQL查詢,每個需要執(zhí)行1秒。因為是并行,處理所有的查詢,也只需要1秒左右。
?php
if(!defined("INCLUDE_MYSQL_OK")) {
define("INCLUDE_MYSQL_OK","");
class MySQL_class {
var $debug = true;
var $db,
$id,
$result, /* 查詢結(jié)果指針 */
$rows, /* 查詢結(jié)果行數(shù) */
$fields, /* 查詢結(jié)果列數(shù) */
$data, /* 數(shù)據(jù)結(jié)果 */
$arows, /* 發(fā)生作用的紀(jì)錄行數(shù)目 */
$iid; /* 上次插入操作后,可能存在的"AUTO_INCREMENT"屬性字段的值,如果為"0",則為空 */
var $user, $pass, $host, $charset;
/*
* 請注意用戶名和密碼是否正確
*/
function Setup ($host, $user, $pass, $charset='utf8') {
$this-host = $host;
$this-user = $user;
$this-pass = $pass;
$this-charset = $charset;
}
function Connect ($db = "") {
global $CFG_MYSQL_INFO;
if (!$this-host) {
$this-host = $CFG_MYSQL_INFO["host"];
}
if (!$this-user) {
$this-user = $CFG_MYSQL_INFO["user"]; /* 在這里作修改 */
}
if (!$this-pass) {
$this-pass = $CFG_MYSQL_INFO["passwd"]; /* 在這里作修改 */
}
if (!$this-charset) {
$this-charset = "utf8"; /* 在這里作修改 */
}
if (empty($db))
$this-db = $CFG_MYSQL_INFO["database"];
else
$this-db = $db;
$this-id = @mysql_connect($this-host, $this-user, $this-pass);
if (!$this-id)
return false;
$this-SelectDB($this-db); /* 定位到指定數(shù)據(jù)庫 */
$this-Query("SET NAMES '".$this-charset."'");
return true;
}
function Close(){
@mysql_close($this-id);
}
function SelectDB ($db) {
if(!@mysql_select_db($db, $this-id))
return false;
else
return true;
}
function Begin () {
$this-result = @mysql_query("START TRANSACTION WITH CONSISTENT SNAPSHOT", $this-id);
if (!$this-result)
return false;
return true;
}
function Commit () {
$this-result = @mysql_query("COMMIT", $this-id);
if (!$this-result)
return false;
return true;
}
function Rollback () {
$this-result = @mysql_query("ROLLBACK", $this-id);
if (!$this-result)
return false;
return true;
}
function Escape ($str) {
$escstr = mysql_escape_string($str);
return $escstr;
}
# 普通查詢功能,主要用于返回結(jié)果是多條記錄的情況
# 請使用 Fetch 方法取得每條記錄信息
function Query ($query) {
$this-result = @mysql_query($query, $this-id);
if (!$this-result)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-rows = @mysql_num_rows($this-result);
$this-fields = @mysql_num_fields($this-result);
if (!$this-rows) return false;
return true;
}
function QuerySql ($query) {
$ret = @mysql_query($query, $this-id);
if ($ret === false)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-result = $ret;
$this-rows = @mysql_num_rows($this-result);
$this-fields = @mysql_num_fields($this-result);
return true;
}
# 如果查詢結(jié)果為單條記錄時使用,返回結(jié)果存儲于數(shù)組 data 中
function QueryRow ($query) {
$this-result = @mysql_query($query, $this-id);
if (!$this-result)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-rows = @mysql_num_rows($this-result);
$this-data = @mysql_fetch_array($this-result, MYSQL_ASSOC);
//MySQL_ErrorMsg ("不能從查詢結(jié)果中取得數(shù)據(jù) $query");
if (!$this-result || !$this-rows)
return false;
return true;
}
# 移動到指定記錄行,將該行結(jié)果儲存于數(shù)組 data 中
function Fetch ($row) {
if(!@mysql_data_seek($this-result, $row))
//MySQL_ErrorMsg ("不能定位到指定數(shù)據(jù)行 $row");
return false;
$this-data = @mysql_fetch_array($this-result, MYSQL_ASSOC);
//MySQL_ErrorMsg ("不能提取指定數(shù)據(jù)行數(shù)據(jù) $row");
if (!$this-data)
return false;
return true;
}
/* 以下方法將作用于 arows */
/* 此方法將作用于 iid */
function Insert ($query) {
$this-result = @mysql_query($query, $this-id);
if (!$this-result)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-arows = @mysql_affected_rows($this-id);
$this-iid = @mysql_insert_id($this-id);
return true;
}
function Update ($query) {
$this-result = @mysql_query($query, $this-id);
if (!$this-result)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-arows = @mysql_affected_rows($this-id);
if (!$this-arows || $this-arows == -1)
return false;
return true;
}
function Delete ($query) {
$this-result = @mysql_query($query, $this-id);
if (!$this-result)
{
if ($this-debug)
MySQL_ErrorMsg ("不能執(zhí)行查詢(query): $query");
else
return false;
}
$this-arows = @mysql_affected_rows($this-id);
return true;
}
function Error (){
return mysql_error()."(".mysql_errno().")";
}
function Errno (){
return mysql_errno();
}
}
/*
* MySQL_ErrorMsg
* 輸出錯誤信息
*/
function MySQL_ErrorMsg ($msg) {
# 關(guān)閉可能影響字符顯示的HTML代碼
echo("/ul/dl/ol\n");
echo("/table/script\n");
# 錯誤信息
$text = "font color=\"#000000\" style=\"font-size: 9pt; line-height: 12pt\"p系統(tǒng)提示:".$msg."br";
$text .= "錯誤信息:";
$text .= mysql_error()."br";
$text .= "錯誤代碼:".mysql_errno()."brbr";
$text .= "請稍候再試,如果問題仍然存在,請與 a href=\"mailto:[email protected]\"系統(tǒng)管理員/a 聯(lián)系!";
$text .= "/font\n";
die($text);
}
}
?
一些細(xì)節(jié)的地方自己修改吧 主要是我在別的文件專門定義了全局變量,你看一遍,把應(yīng)改的地方改一下就好了
新聞名稱:多并發(fā)php查詢數(shù)據(jù)代碼 多并發(fā)php查詢數(shù)據(jù)代碼是多少
本文網(wǎng)址:http://www.jbt999.com/article6/hjjdog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、網(wǎng)頁設(shè)計公司、建站公司、網(wǎng)站收錄、網(wǎng)站營銷、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)