ORM 쿼리 결과 : Array vs result hange iterator interface에 랩핑됩니다.
-
22-08-2019 - |
문제
좋아요, 여기에 프로를위한 것이 있습니다.
몇 년 동안, 나는 내가 지명 한 내 자신의 php orm/activerecord 구현 작업을 해왔습니다. Pork.dbobject.
그것은 몇 년 전에 우리 모두가 본 영화 '5 분 만에 레일로 자신의 사이트 만들기'를 기반으로 느슨합니다. 당신은 다음과 같은 일을 할 수 있습니다.
$clients = dbObject::Search("Client", array("ID > 500"));
또는
$client = new Client(218); // fetch row with id 218 from client table
또는
$projects = $client->Find('Project');
이렇게하면 데이터베이스에서 하나 이상의 행을 가져 오거나 dbobject로 감싸고 하나의 배열로 반환하거나 결과가 없다는 거짓을 반환합니다.
이 모든 것이 수십 개의 사이트와 백엔드에서 완벽하게 작동했지만 이제 내 동료는이를 사용하여 거대한 로그 패러를 만들고 여기에서 메모리 사용량 문제를 시작합니다.
그가 실행하는 쿼리는 20.000 행 이상을 반환 할 수 있습니다.
명백한 해결책은 반복자 배열 대신 인터페이스. 결과 세트에서 모든 레코드를 즉시 가져 오지 않아야하지만 생성 된 데이터베이스 쿼리의 결과 리소스를 보유하고 배열 인 것처럼 개체를 통과 할 때 내부적으로 MySQL_Fetch_*를 사용해야합니다.
이제 우리는 나의 진짜 질문에 도달합니다. 아무런 문제없이 이것을 할 수 있습니까? 데이터베이스가 여러 개의 열린 결과 세트를 처리하고 혼합하여 한동안 메모리에 보관할 수 있습니까?
예를 들어, 20 개의 물체를 가져오고, 반복하고,이 20 개의 각각이 5 개의 다른 것을 가져 오게하십시오. 이렇게하면 여러 가지 다른 결과 핸들이 메모리에 유지되는 루프가 생성됩니다.
이러한 객체 중 하나를 직렬화 할 수는 없지만 PHP5의 문제 없이이 문제를 구현할 수 있습니까? 아니면 데이터베이스 인터페이스가 문제를 줄 수 있습니까?
해결책
사용중인 데이터베이스 및 데이터베이스 구성에 따라 다릅니다.
MySQL의 경우 버퍼링 된 쿼리를 사용해야합니다. PDO에서는 다음과 같이 설정합니다.
$myPdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
이는 모든 데이터가 클라이언트에게 전송 될 것임을 의미합니다 (PHP에서 모든 데이터를 가져 오는 것과 동일하지 않음).
다른 (아마도 더 나쁜) 대안은 결과 세트가 여전히 열려있는 결과로 실행되는 쿼리를 감지 할 때마다 새 데이터베이스 연결을 여는 것입니다.
정상 mysql_query()
버퍼링 된 쿼리를 사용하므로 여러 결과 세트에서 작동합니다.