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(...);

    ...
}