programing

PDO 쿼리 vs 실행

javaba 2022. 11. 25. 21:08
반응형

PDO 쿼리 vs 실행

둘 다 같은 일을 하는 게 다를 뿐인가요?

사용하는 것 외에 다른 점이 있습니까?prepare사이에

$sth = $db->query("SELECT * FROM table");
$result = $sth->fetchAll();

그리고.

$sth = $db->prepare("SELECT * FROM table");
$sth->execute();
$result = $sth->fetchAll();

?

query 는 매개 변수화된 데이터 없이 표준 SQL 문을 실행합니다.

execute 는 파라미터를 바인드하여 이스케이프 또는 따옴표를 피할 수 있는 준비된 문을 실행합니다. execute쿼리를 여러 번 반복하는 경우에도 성능이 향상됩니다.준비된 스테이트먼트의 예:

$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories);
$sth->bindParam(':colour', $colour);
$sth->execute();
// $calories or $color do not need to be escaped or quoted since the
//    data is separated from the query

베스트 프랙티스는 준비된 스테이트먼트를 고수하여 보안을 강화하는 것입니다.

다음 항목도 참조하십시오.PDO 준비 문장은 SQL 주입을 방지하기에 충분한가?

아니, 같지 않아.클라이언트 측에서 제공되는 이스케이프와는 별도로 서버 측에서 준비된 스테이트먼트가 1회 컴파일되어 실행 시마다 다른 파라미터를 전달할 수 있습니다.즉, 다음과 같은 작업을 수행할 수 있습니다.

$sth = $db->prepare("SELECT * FROM table WHERE foo = ?");
$sth->execute(array(1));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);

$sth->execute(array(2));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);

소규모에서는 눈에 띄지 않지만 일반적으로 성능이 향상됩니다.준비된 문(MySQL 버전)대한 자세한 내용은 여기를 참조하십시오.

Gilean의 답변은 훌륭합니다만, 베스트 프랙티스에는 드문 예외가 있는 경우가 있기 때문에, 어느 쪽이 최적인지를 확인하기 위해서, 양쪽 모두의 환경을 테스트하는 것이 좋을지도 모릅니다.

한 가지 사례로, 나는 그것을 발견했다.queryMS SQL Server용 Microsoft ODBC 드라이버가 제대로 지원되지 않는 상태에서 PHP7을 실행하는 Ubuntu Linux 상자에서 신뢰할 수 있는 데이터를 대량 전송했기 때문에 작업이 더 빨라졌습니다.

이 질문에 도달하게 된 것은 ETL에 대한 긴 실행 대본이 있었기 때문입니다.이 스크립트는 속도를 높이기 위해 짜고 있었습니다.라고 직감적으로 생각되었다query보다 빠를 수 있다prepare&execute두 개의 함수가 아닌 하나의 함수만을 호출했기 때문입니다.파라미터 바인딩 조작은 뛰어난 보호 기능을 제공하지만 비용이 많이 들고 불필요한 경우 회피할 수 있습니다.

몇 가지 드문 조건이 있습니다.

  1. Microsoft ODBC 드라이버에서 지원되지 않기 때문에 준비된 문을 재사용할 수 없는 경우.

  2. 만약 당신이 입력과 간단한 탈출을 걱정할 필요가 없다면 받아들일 수긍할 수 있습니다.Microsoft ODBC 드라이버에서는 특정 데이터 유형의 바인딩이 지원되지 않기 때문일 수 있습니다.

  3. PDO::lastInsertId 는 Microsoft ODBC 드라이버에서 지원되지 않습니다.

다음은 환경을 테스트하기 위해 사용한 방법이며, 이를 복제하거나 더 나은 방법을 사용할 수 있기를 바랍니다.

시작하기 전에 Microsoft SQL Server에서 기본 테이블을 만들었습니다.

CREATE TABLE performancetest (
    sid INT IDENTITY PRIMARY KEY,
    id INT,
    val VARCHAR(100)
);

퍼포먼스 메트릭의 기본적인 타이밍 테스트입니다.

$logs = [];

$test = function (String $type, Int $count = 3000) use ($pdo, &$logs) {
    $start = microtime(true);
    $i = 0;
    while ($i < $count) {
        $sql = "INSERT INTO performancetest (id, val) OUTPUT INSERTED.sid VALUES ($i,'value $i')";
        if ($type === 'query') {
            $smt = $pdo->query($sql);
        } else {
            $smt = $pdo->prepare($sql);
            $smt ->execute();
        }
        $sid = $smt->fetch(PDO::FETCH_ASSOC)['sid'];
        $i++;
    }
    $total = (microtime(true) - $start);
    $logs[$type] []= $total;
    echo "$total $type\n";
};

$trials = 15;
$i = 0;
while ($i < $trials) {
    if (random_int(0,1) === 0) {
        $test('query');
    } else {
        $test('prepare');
    }
    $i++;
}

foreach ($logs as $type => $log) {
    $total = 0;
    foreach ($log as $record) {
        $total += $record;
    }
    $count = count($log);
    echo "($count) $type Average: ".$total/$count.PHP_EOL;
}

해 본이 있으며, 더 수 있습니다.또한 이 테스트 결과를 20~30% 고속으로 얻을 수 있습니다.queryprepare/execute

.81289669342 비 8
.8688418865204 ★
4.2948560714722 ©
.9536417419 리 95
.9051351547241 " "
4.332102060318 리 3
.9672858715057 ★
5. 5.0667371749878 리78
3.8260300159454 리 82
4. 4.0791549682617 」
4.3775160312653 리 37
3.6910600662231 3131
5. 5.1208210945129
6. 6.2671611309052
.3791449069977 ★
평균:6(7) 준비: 6.0673267160143
평균 (8) ( : 4.3276024162769

이 테스트가 MySQL과 같은 다른 환경에서 어떻게 비교되는지 궁금합니다.

언급URL : https://stackoverflow.com/questions/4700623/pdos-query-vs-execute

반응형