Edit report at https://bugs.php.net/bug.php?id=53458&edit=1
ID: 53458 Updated by: m...@php.net Reported by: don at smugmug dot com Summary: Non-linear performance degradation on certain prepared SELECT queries Status: Analyzed Type: Bug Package: PDO related Operating System: CentOS 5.5 PHP Version: 5.3.3 Block user comment: N Private report: N New Comment: Nope, it's not obvious at the first glance, but if you fetch 10k rows with 10k params you have N * 1e4 * 1e4 (Ne8) iterations, where N stands for the number of callbacks per fetched row. While, if you fetch 1k rows with 1k params for 10 times, it's N * 10 * 1e3 * 1e3 (Ne7) (90% less). Previous Comments: ------------------------------------------------------------------------ [2013-03-19 17:44:30] don at smugmug dot com Sorry for the script getting lost, been awhile. :) Here's a gist with it: https://gist.github.com/onethumb/5198291 The thing that still leaves me wondering after your analysis is why doing a prepared SELECT on 1K rows, ten times, results in a >10X faster return than a single SELECT on 10K rows? Presumably, we'd have the same # of calls both ways? I just validated against 5.4.10, too. Same problem. ------------------------------------------------------------------------ [2013-03-19 16:34:04] m...@php.net The test script is not accessible anymore, so I assume it is about $stm->execute($a10kArray) If that is the case, then the issue might be described as follows: Each element in the array to stm->execute() is registered as a bound parameter, for which the param_hook callback is called twice (normalize and alloc) and once when everything is done (free). So for a 10k array, this are 30k callbacks into the pdo driver. When fetching a row, the param_hook callback is called twice for each param (fetch_pre and fetch_post), i.e. 20k callbacks. So for a 10k rowset add 200M calls. In numbers: 200,030,000 indirect calls to the param_hook callback of the underlying pdo driver. Iterating over the 10k params twice for each of the 10k rows is nearly (twice in a debug build) as expensive as calling the param_hook itself. Add this two things up, and you easily wait a second for your result set. ------------------------------------------------------------------------ [2010-12-03 04:27:43] w...@php.net from a twitter conversation with Don, the heart of this issue is that the there appears to be a difference in the performance of fetch() or fetchAll() depending on whether query() or prepare() + execute() were used. Given that query() is really just prepare() + execute() under the covers, it is difficult to explain this difference. ------------------------------------------------------------------------ [2010-12-03 03:36:14] don at smugmug dot com FYI, setting PDO::MYSQL_ATTR_USE_BUFFERED_QUERY to true/false didn't have a large impact. Still ~10X slower than any of the other methods either way. (Buffered was slightly faster) ------------------------------------------------------------------------ [2010-12-02 23:39:10] don at smugmug dot com Here's my PHP build configuration: './configure' '--enable-exif' '--with-gd' '--enable-gd-native-ttf' '--with-jpeg- dir=/usr' '--with-png-dir=/usr' '--with-freetype-dir=/usr' '--with-zlib' '-- enable-inline-optimization' '--with-bz2' '--with-apxs2' '--with-xmlrpc' '--with- curl' '--with-libdir=lib64' '--with-pdo-mysql=mysqlnd' '--with-mcrypt' '--enable- bcmath' '--with-gmp' '--enable-mbstring' '--with-mysql=mysqlnd' '--with-openssl' '--with-mysqli=mysqlnd' ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=53458 -- Edit this bug report at https://bugs.php.net/bug.php?id=53458&edit=1