for quite big $db_prefix arrays db prefixing can take some time and so decrease performance.
e.g. i 've tested an $db_prefix arrray with ~25entries, which lead to about 20ms more page generation time on /admin (200ms instead of 180).
the attached patch changes db_prefix_tables() to use preg_replace, which seems to be a bit faster (got 193ms instead of 200ms).
further this patch changes matching, so that e.g. profile would match to {profile_fields} and {profile_values}. this allows reducing the size of $db_prefix substantially, think of e.g. the flexinode tables. it's possible to avoid this match by appending a '}', e.g. using 'users}' would match only to 'users' and not to 'users_roles'
so in my use case, i was able to reduce the /admin page generation time to 185ms with an equal prefixing.
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | db_prefix-before.png | 99 KB | mrfelton |
| #15 | db_prefix-after.png | 97.36 KB | mrfelton |
| #15 | 42827-db-prefix-performance-v2.patch | 2.58 KB | mrfelton |
| #6 | db_prefix3.patch | 2.9 KB | fago |
| #2 | db_prefix2.patch | 2.81 KB | fago |
Comments
Comment #1
dries commentedLooks cool but coding style needs work. It's also a good idea to document the new features.
Comment #2
fagoi've attached an updated patch.
it includes some documentation in the default settings.php file.
Comment #3
fagoComment #4
killes@www.drop.org commentedI am wondering whether we could make $search and $replace static variables so we only need to compute them once per page view.
Comment #5
fagogood idea, i'll try it
Comment #6
fagothis seems to be another fine improvement.
now, i get only 182-183ms on /admin for my test case.
Comment #7
drummComment #8
coreb commented(Moving x.y.z version to a real version number) Feature Request => 6.x-dev
Comment #9
webchickDoes not apply.
Comment #10
panchoNeed to move this to the D7 queue.
Comment #11
tisho-1 commentedThis patch has been a lifesaver for me. With 160 shared tables I saw a *** 1 second *** overhead! After applying the patch this overhead is gone.
You can see more information on the problem in this thread: http://groups.drupal.org/node/18369
I hope this makes it at least into 7.x!
Thank you!
Comment #12
catchChanging to task and subscribing.
Comment #13
mrfelton commentedThis patch is a must if you're using civicrm which required that you db_prefix over 125 tables to get views integration.
Comment #14
mrfelton commentedAdding 'Performance' tag.
Comment #15
mrfelton commentedI just benchmarked the
db_prefix_tables()this using xdebug and webgrind with a setup using 125 prefixed tables (due to civicrm)BEFORE
Invocation count: 457ms
Total self cost: 961ms
Total inclusive cost: 1339ms
AFTER
Invocation count: 456ms
Total self cost: 40ms
Total inclusive cost: 79ms
The db_prefix_tables() function went from being THE most expensive function that took up almost 20% of processing time, down, to the 25th most expensive function taking up less than 2% of the total time.
See attached screenshots
Also attached is an updated version of the patch that was created against Druapl 6.14
Comment #16
catchdb_prefix_tables() doesn't exist in D7. I'm not sure if the D7 implementation suffers from any of the same issues, but that's being refactored over at #302327: Support cross-schema/database prefixing like we claim to.
So I'm moving this back to D6. Also bumping to critical since 1/5 of request time is massive.
mrfelton - could you post benchmarks?
Comment #17
catchComment #18
mrfelton commented@catch: What kind of benchmarks do you want to see? Do the screenshots above not show enough?
Comment #19
catchMy bad, I completely ignored the screenshots :(
Comment #20
mrfelton commentedany movement here - would sure be great to see this fixed in core. The performance hit incurred here is seriously large.
Comment #21
jonne_jvl commentedTried it on a 6.17 multisite setup.
Works fine, similar speedup as reported in #1 of around ~20ms
I dont read regex, sorry.
Comment #23
dpearcefl commentedIf this is still needed, please submit the patch with fixes.
Comment #24
dpearcefl commentedComment #25
lyricnz commentedThe strtr/str_replace issue was recently fixed in D7/D8 over on #561422: Replace strtr() with str_replace() for db prefixing. I think that solution removes the need to change the meaning of the tablenames in $db_prefix? If others agree, suggest closing this as duplicate (of the "needs backport" over there).
Comment #26
andypostLatest measurements #561422: Replace strtr() with str_replace() for db prefixing