MySQL 버퍼링된 쿼리 및 버퍼링되지 않은 쿼리
쿼리는 기본적으로 버퍼링된 모드를 사용합니다. 즉, 쿼리 결과가 MySQL 서버에서 PHP로 즉시 전송된 다음 PHP 프로세스의 메모리에 보관됩니다. 이것은 행 수를 세고 현재 결과 포인터를 이동(검색)하는 것과 같은 추가 작업을 허용합니다. 또한 결과 집합에서 작업하는 동안 동일한 연결에 대해 추가 쿼리를 실행할 수 있습니다. 버퍼링된 모드의 단점은 결과 집합이 클수록 메모리가 많이 필요할 수 있다는 것입니다. 메모리는 결과 집합에 대한 모든 참조가 설정 해제되거나 결과 집합이 명시적으로 해제될 때까지 점유된 상태로 유지되며, 이는 늦어도 요청이 종료되는 동안 자동으로 발생합니다. 전체 결과 세트가 한 번에 저장되기 때문에 "store result"이라는 용어는 버퍼링 모드에도 사용됩니다.
메모: libmysqlclient를 라이브러리로 사용할 때 PHP의 메모리 제한은 데이터를 PHP 변수로 가져오지 않는 한 결과 세트에 사용된 메모리를 계산하지 않습니다. mysqlnd를 사용하면 계산된 메모리에 전체 결과 세트가 포함됩니다.
버퍼링되지 않은 MySQL 쿼리는 쿼리를 실행한 다음 데이터가 아직 가져오기를 위해 MySQL 서버에서 기다리는 동안 리소스를 반환합니다. 이것은 PHP 측에서 더 적은 메모리를 사용하지만 서버의 로드를 증가시킬 수 있습니다. 전체 결과 집합을 서버에서 가져오지 않는 한 동일한 연결을 통해 더 이상 쿼리를 보낼 수 없습니다. 버퍼링되지 않은 쿼리는 "use result"이라고도 합니다.
이러한 특성에 따라 버퍼링된 쿼리는 제한된 결과 집합만 예상하거나 모든 행을 읽기 전에 반환된 행의 양을 알아야 하는 경우에 사용해야 합니다. 더 큰 결과를 기대하는 경우 버퍼되지 않은 모드를 사용해야 합니다.
버퍼링된 쿼리가 기본값이므로 아래 예제에서는 각 API로 버퍼링되지 않은 쿼리를 실행하는 방법을 보여줍니다.
예제 #1 버퍼되지 않은 쿼리 예제: mysqli
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
if ($uresult) {
while ($row = $uresult->fetch_assoc()) {
echo $row['Name'] . PHP_EOL;
}
}
?>
예제 #2 버퍼되지 않은 쿼리 예제: pdo_mysql
<?php
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$uresult = $pdo->query("SELECT Name FROM City");
if ($uresult) {
while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
echo $row['Name'] . PHP_EOL;
}
}
?>