Edit report at https://bugs.php.net/bug.php?id=53458&edit=1

 ID:                 53458
 Comment by:         don at smugmug dot com
 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:

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.


Previous Comments:
------------------------------------------------------------------------
[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'

------------------------------------------------------------------------
[2010-12-02 23:29:50] don at smugmug dot com

Description:
------------
When retrieving results from prepared PDO statements against MySQL, we get 
performance that diverges from expected by 10X or more on results as low as 
10000 
rows.  This only occurs for 'SELECT ... WHERE Id IN ( .. )' queries.  

The attached script provides two PDO prepared approaches ('row-prepared', 
default, 
and 'all-prepared') as well as a variety of control methods that use 
non-prepared 
PDO queries, straight MySQL, and prepared queries using MySQLi.  Only PDO with 
prepared queries exhibits the problem.

If the query is broken up into chunks that return 1000 rows or less prior to 
execution, then combined afterwards in PHP, performance is as expected.

Test script:
---------------
You can get the sample script from: 
http://www.smugmug.com/test/pdo-problem.php.gz

Expected result:
----------------
pdo-problem.php?type=row-prepared and pdo-problem.php?type=all-prepared should 
return in ~0.5s, like the other types (row, all, chunk, mysql, mysqli).

Actual result:
--------------
pdo-problem.php?type=row-prepared and pdo-problem.php?type=all-prepared return 
in 
~6s instead of ~0.5s


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=53458&edit=1

Reply via email to