2013-05-03 79 views
0

我在編寫PHP腳本時遇到了以下問題。我需要將變量長度數組中的前兩個整數存儲到數據庫表中,將其刪除並重復此操作,直到數組爲空。我可以用while循環來做,但是我讀到應該避免在循環中寫入SQL語句,因爲性能受到影響。用PHP語言循環內部的SQL語句,好主意?

一個simpliefied例如:

while(count($array) > 0){ 
if ($sql = $db_connect->prepare("INSERT INTO table (number1, number2) VALUES (?,?)")){ 
         $sql->bind_param('ii',$array[0],$array[1]); 
         $sql->execute(); 
         $sql->close(); 
        } 
         array_shift($array); 
         array_shift($array); 
} 

這是最好的方式,如果不是,有什麼更好的辦法?

+0

每次循環迭代時執行數據庫操作都可能導致問題。您需要執行批處理以減少到數據庫的訪問次數。 – Lion 2013-05-03 17:44:18

+0

好主意?不,沒有。 – rdlowrey 2013-05-03 17:44:54

回答

1

你可以做這樣的事情,這是遠遠快藏漢:

的僞代碼:

$stack = array(); 
while(count($array) > 0){ 
    array_push($stack, "(" . $array[0] . ", " . $array[1] . ")"); 
    array_shift($array); 
    array_shift($array); 
} 
if ($sql = $db_connect->prepare("INSERT INTO table (number1, number2) 
           VALUES " . implode(',', $stack))){ 
    $sql->execute(); 
    $sql->close(); 
} 

這裏唯一的問題是,它不是一個「MySQL的安全」插入,你將需要修復的!

這將生成和保存值的數組。在1個查詢中,它將一次插入所有值,在那裏你需要更少的MySQL時間。

+0

看起來不錯,謝謝!但是,您對MySQL安全部分意味着什麼? – Jenthe 2013-05-04 12:33:25

+0

我只是把數組直接放在查詢中,所以沒有參數,我沒有使用'mysql_real_escape_string',所以可能沒有MySQL注入。 – Niels 2013-05-04 12:48:15

+0

只是爲了幫助其他人有同樣的問題:上面的代碼是完美的,但不要忘記添加一個逗號作爲「膠水」的內爆功能,否則它不會工作!示例:implode(「,」,$ stack) – Jenthe 2013-05-06 11:06:29

0

無論你通過一個或一個陣列中運行它們一個你會好起來的關於MySQL

$sql = "INSERT INTO table(number1, number2) VALUES"; 
$params = array(); 
foreach($array as $item) { 
    $sql .= "(?,?),\n"; 
    $params[] = $item; 
} 
$sql = rtrim($sql, ",\n") . ';'; 
$sql = $db_connect->prepare($sql); 
foreach($params as $param) { 
    $sql->bind_param('ii', $param[ 0 ], $param[ 1 ]); 
} 
$sql->execute(); 
$sql->close(); 
0

寫BULK INSERT語句,少命中,INSERT語句是不會做出明顯的性能損失,從我的經驗。

數據庫連接只打開一次,所以它不是一個大問題。我猜如果你正在做一些瘋狂的查詢,那可能是。

0

我覺得只要你的循環條件是安全的(會在第一時間打破),你從中得到的東西..它的確定

0

在ColdFusion中,您可以將循環放入查詢中而不是其他方式。我不是一個PHP程序員,但我的一般信念是,大多數可以用語言a完成的事情也可以用語言b完成。這段代碼顯示了這個概念。你應該能夠弄清楚一個PHP版本。

<cfquery> 
insert into mytable 
(field1, field2) 
select null, null 
from SomeSmallTable 
where 1=2 
<cfloop from="1' to="#arrayLen(myArray)#" index="i"> 
select <cfqueryparam value="myArray[i][1] 
, <cfqueryparam value="myArray[i][] 
from SomeSmallTable 
</cfloop> 
</cfquery> 

當我看這個辦法我自己,我發現它比內側Oracle和SQL Server查詢循環更快。我發現紅磚比較慢。

這種方法存在限制。 Sql服務器有最大數量的參數它將接受和最大查詢長度。其他數據庫引擎可能不錯,我還沒有發現它們。