Req #66794 [Com]: dba_fetch() cdb handler implements $skip inefficiently
| From: | harsh0sharma14 at gmail dot com | Date: | Wed, 23 Feb 2022 11:26:37 +0000 |
| Subject: | Req #66794 [Com]: dba_fetch() cdb handler implements $skip inefficiently | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-239993@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66794&edit=1
ID: 66794
Comment by: harsh0sharma14 at gmail dot com
Reported by: doug at opendns dot com
Summary: dba_fetch() cdb handler implements $skip
inefficiently
Status: Open
Type: Feature/Change Request
Package: DBM/DBA related
Operating System: Any
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Thanks for sharing..!!
Previous Comments:
------------------------------------------------------------------------
[2014-02-28 05:02:30] doug at opendns dot com
Clarified bug title
------------------------------------------------------------------------
[2014-02-28 04:58:35] doug at opendns dot com
Description:
------------
---
From manual page: http://www.php.net/function.dba-fetch
---
This is in reference to this bit of the source, which dates back to 2002, so it's applicable to
pretty much any version of php since 4.3:
https://github.com/php/php-src/blob/master/ext/dba/dba_cdb.c#L160
When you pass a value for $skip to dba_fetch() when reading a cdb database, it'll do $skip
reads to bypass those entries. Since a common use case is to do this in a loop (see script below)
to read an indeterminate number of duplicate keys from a database, If there end up being 100
entries, you're actually doing several thousand disk operations.
Test script:
---------------
<?php
// Write a sample cdb to demo on
$values = array_fill(0, 100, 'test value');
$cdb = dba_open('test.cdb', 'n', 'cdb');
foreach($values as $value) dba_insert('test key', $value, $cdb);
dba_close($cdb);
// Now actually show the issue (see attached dtruss link for what's happening)
$cdb = dba_open('test.cdb', 'r', 'cdb');
$cdbSkip = 0;
while ($result = dba_fetch('test key', $cdbSkip, $cdb)) {
$cdbSkip++;
}
Expected result:
----------------
I'd expect approximately 100 read requests against the cdb from the latter half of the script
Actual result:
--------------
See this output from dtruss: https://gist.github.com/tabacco/86bd9f4b1fd267a62be2
Note the high number of seek and read operations to fetch 100 rows.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66794&edit=1