Php 准备好的语句应该放在函数中吗?
这个问题是关于性能和推荐的程序结构的:如果在函数中放入一个准备好的语句,那么每次调用该函数时,准备好的语句会再次准备吗?例如:Php 准备好的语句应该放在函数中吗?,php,pdo,Php,Pdo,这个问题是关于性能和推荐的程序结构的:如果在函数中放入一个准备好的语句,那么每次调用该函数时,准备好的语句会再次准备吗?例如: function check($x) { global $DB; $stmt = $DB->prepare( "SELECT id FROM table WHERE code = :code;" ); $stmt->bindparam(':code', $x); try {
function check($x)
{
global $DB;
$stmt = $DB->prepare(
"SELECT id FROM table WHERE code = :code;"
);
$stmt->bindparam(':code', $x);
try {
$stmt->execute();
return $stmt->fetchColumn();
} catch (Exception $e) {
...
}
}
性能方面,将$DB->prepare()
拉到函数之外会更好吗?建议的结构是什么
global $DB;
$stmt = $DB->prepare(
"SELECT id FROM table WHERE code = :code;"
);
function check($stmt, $x)
{
$stmt->bindparam(':code', $x);
try {
$stmt->execute();
return $stmt->fetchColumn();
} catch (Exception $e) {
...
}
}
对于与此类似的性能问题,同样重要的是考虑所涉及的操作的<强>比例>强> >成本> /强>,在这种情况下,<代码> dB:PrimeAube()/<代码>,除其他事项外,
如果函数check()
只调用一次,或者每次请求、页面加载等调用几次,那么这真的很重要吗
但是,如果函数check()
将被调用数十次(或者更糟的是,调用100次或更多),那么您应该检查DB::prepare()
的开销。你应该设定基准。您可以对单个操作执行此操作,但在这种情况下,我怀疑(没有具体依据:P)它将产生1ms(毫秒)的差异。相反,做一个更糟糕的情况。如果您认为该函数在某些情况下可以被调用50次,那么就以此为基准
老实说?考虑到该函数调用一个DB操作,网络延迟和DB服务器操作将比单个的DB::prepare()
花费更多
再次,考虑规模和成本,并执行一些基准。
更新2020-12-27 2:21 UTC 回应 <>忘记提到要考虑的性能类型,例如CPU、内存、存储、网络往返时间等。类型将决定您可以执行的基准类型。现在,我将假设CPU使用率,特别是操作完成的速度 假设一个请求中对check()
函数的平均调用次数为30次。如果是一个范围,如20~30,选择上限
我们可以从单独的mysqli::prepare()
函数开始:
$db = new mysqli(...);
$start = microtime(true);
for ($i = 0; $i < 30; $i++) {
$db->prepare('SELECT id FROM table WHERE code = ?');
}
$time = microtime(true) - $start;
var_dump($time); // eg, 0.004544...s = 4.5ms
我确信有更好的解决方案,但在这种情况下,我更希望这样做,而不是将
mysqli::prepare()
移出函数。每次调用prepare时,它都会准备一条语句。它是在函数内部还是外部都是完全无关的。您的第二个变体对程序结构不利:在第一个变体中,您只需调用check($x),在第二个变体中,您必须首先准备和try…catch
@YourCommonSense你能告诉我什么问题吗?@YourCommonSense有人告诉我,在第一种方法中,每次调用函数时都会准备语句。在第二种情况下,它只需要“准备”一次并运行多次。这是真的吗?是的,但是你要打多少次电话?用例是什么?谢谢。关于如何在DB::prepare()
上进行基准测试,您能给出一些建议吗?尼克更新了我的答案。你的建议是什么,你通常怎么做,把语句准备放在函数内部还是外部。。此外,正如一句名言所说,过早优化是万恶之源:你应该对已经很慢的东西进行基准测试,而不仅仅是一时兴起就对东西进行左右基准测试。它会导致你做一些奇怪的事情,引入bug,使你的应用程序整体运行缓慢使语句保持静态是明智的做法
function check($db, $code) {
static $stmt = null;
if (!$stmt) {
$stmt = $db->prepare(...);
}
$stmt->bind_param(...);
...
}