php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #66794 dba_fetch() cdb handler implements $skip inefficiently
Submitted: 2014-02-28 04:58 UTC Modified: 2014-02-28 05:02 UTC
Votes:5
Avg. Score:4.8 ± 0.4
Reproduced:5 of 5 (100.0%)
Same Version:2 (40.0%)
Same OS:2 (40.0%)
From: doug at opendns dot com Assigned:
Status: Open Package: DBM/DBA related
PHP Version: Irrelevant OS: Any
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: doug at opendns dot com
New email:
PHP Version: OS:

 

 [2014-02-28 04:58 UTC] 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.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-28 05:02 UTC] doug at opendns dot com
-Summary: dba_fetch() skip parameter is inefficient when accessing cdbs +Summary: dba_fetch() cdb handler implements $skip inefficiently
 [2014-02-28 05:02 UTC] doug at opendns dot com
Clarified bug title
 [2022-02-23 11:26 UTC] harsh0sharma14 at gmail dot com
Thanks for sharing..!!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 10:01:28 2024 UTC