During load testing on examiner two queries from filter.module show up in the top 10 or so slow queries via mysqlsla (most of the rest are from entity and menu cache misses), this is simply due to frequency - any page displaying a comment form runs both of those queries. Very simple patch to cache them. Sites using db caching will see no benefit or harm either way - it's only two cache entries per-site so building the cache is extremely cheap and it's cleared pretty rarely. Sites using an alternate caching backend will see as much as 10% load taken of MySQL depending on what's going on elsewhere (average number of MySQL queries per page is around 20).

This is unlikely to have an effect on overall page execution time, it's mainly about shifting load off MySQL.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Anonymous’s picture

i like the idea, and the code looks good. won't RTBC it until a few other eyes have looked at it.

one tiny thing that stands out (but is not a problem invented by this patch) is the use of $cached vs $cache in cache_get() calls.

we seem to use $cache more, but again, this inconsistency is across drupal, not just this patch.

catch’s picture

I prefer $cached because it's closer to English - if cached, return the cached data, that sort of thing.

kscheirer’s picture

Status: Needs review » Reviewed & tested by the community

looks good to me as well.

Dries’s picture

It would be really great if we had a proper API for those optimizations that made this behavior more explicit.

sun’s picture

Status: Reviewed & tested by the community » Needs work
+++ modules/filter/filter.module	13 Jul 2010 06:56:08 -0000
@@ -375,14 +375,20 @@ function filter_modules_disabled($module
+    if ($cached = cache_get('formats_all')) {

Bad namespace -- this cache entry is from Filter module, so must be prefixed with "filter[_:]"

Effectively questioning, why not simply __FUNCTION__ ?

+++ modules/filter/filter.module	13 Jul 2010 06:56:08 -0000
@@ -625,9 +633,15 @@ function filter_list_format($format_id) 
+    if ($cached = cache_get('filters_all')) {

Same here, although the key is (almost) in the correct namespace this time. However, "filters_all" is not very descriptive.

Again, __FUNCTION__ would be cleaner here.

Powered by Dreditor.

sun’s picture

Status: Needs work » Needs review
FileSize
2.43 KB

Furthermore, when caching data that is otherwise retrieved through a query using ->addTag('translatable'), then the cache cid key needs to have a language suffix.

Attached patch should be ready to fly -- and is also a requirement for #903730: Missing drupal_alter() for text formats and filters

sun’s picture

Sorry, forgot that it's $language->language now.

Status: Needs review » Needs work

The last submitted patch, drupal.filter-format-cache.7.patch, failed testing.

dagmar’s picture

Status: Needs work » Needs review
FileSize
2.44 KB
+  cache_clear_all('filters_all', 'cache', TRUE);

Should be

+  cache_clear_all('filter_list_format', 'cache', TRUE);
sun’s picture

Status: Needs review » Reviewed & tested by the community

Ah, thanks! - stupid me.

sun’s picture

Issue tags: -Performance

#9: drupal.filter-format-cache.9.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work
Issue tags: +Performance

The last submitted patch, drupal.filter-format-cache.9.patch, failed testing.

dagmar’s picture

Status: Needs work » Needs review
FileSize
2.5 KB

Rerolled

sun’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

webchick’s picture

Status: Reviewed & tested by the community » Fixed

This seems like a sensible performance improvement.

Committed to HEAD. Thanks!

moshe weitzman’s picture

GRRRRUUUUMMMMMMMBBBBBLLLLLEEEE.

You guys snuck this by me. This went from needs to work to committed in 90 mins.

The queries we are saving here are again single table, fully indexed queries. They are stupid simple. Once again, you guys are just afraid of relying on your DB layer and using caching layer instead. This adds a lot of complexity to Drupal (cache expiration, stampede, general developer WTF when stuff won't change).

Please rollback. It is *not* a performance improvement, as webchick says. This is killing Drupal, one knife cut at a time.

webchick’s picture

Status: Fixed » Needs review

EEK! Don't GRRUMMBLLEEE at me! :D

Ok, sorry. I didn't realize this would be contentious.

Rolled back. Marking back to "needs review" so we can come to a consensus about what to do here.

chx’s picture

sigh. we are not afraid of the database. the database is slow. memcache is fast. if you want to postpone to Drupal 8, oh well. I want memcache in core for D8 just fyi.

David_Rothstein’s picture

For a site using the default database cache, I wonder if this was a performance hit rather than an improvement (it swaps one database query for another, plus then you have the overhead of unserialize in the caching layer).

Even for Drupal 7, is there some hack we could use to make drupal_static() swappable? Then a contrib module could override drupal_static() and allow some of those "static" variables to persist between page requests and be stored in memcache, etc, but other sites wouldn't have to deal with it.

sun’s picture

Version: 7.x-dev » 8.x-dev

@David: That's exactly what the patch in #924616: Make database cache leverage static cache by default intended to do.

While this patch could be considered as improvement for D7, it is too late to consider it now, especially as it seems to require more discussion. Thus, moving to D8. It may be backported later, if we happen to do this performance improvement for D8. For the current D7 queue, we only consider absolutely required patches.

David_Rothstein’s picture

I agree the other issue would allow that, but would also require bigger changes (lots of code would have to switch to using cache_get, etc). The idea here would be to simply leave things as they are, but allow contrib to hook into the existing drupal_static() mechanism and turn some of the static caches into persistent caches if it wanted to. As a stopgap for Drupal 7.

Difficult to do though, I guess - since drupal_static() is called so often and so early, it would probably be hard to make it cleanly swappable or alterable.

catch’s picture

There are only 3-4 queries like this left in D7, 'cos I almost got them all before moshe started pushing back really hard. I imagine I could swap the text format element out with http://drupal.org/project/performance_hacks and add a caching wrapper there. It's ugly but that's what the module's for.

Also I already gave very good reasons why these make sense (can't run them on slaves, even if the individual query is slow the total time on a well optimized site can be 10% of the time in MySQL overall 'cos there's so many), writing this off as fear is FUD.

carlos8f’s picture

Version: 8.x-dev » 7.x-dev

I disagree with @moshe that patches like this are killing Drupal. One might argue that this is a 'misuse' of the cache API, substituting a cache_get() that is *potentially* slower than a straight query. But in reality the cache API is meant to be pluggable and changes like this allow sites that care about scalability to scale without hacking or forking core. Let's keep 7.x in mind, this is not a huge patch.

dagmar’s picture

Title: Cache filter/format queries » Cache filter/format queries and allow contrib to alter them
FileSize
2.82 KB

I'm attaching a new patch, please if you have some time, read http://drupal.org/node/903730#comment-3515902 to understand the reasons for this patch.

catch’s picture

Please, please do not add API changes (let alone undocumented new hooks) to this poor issue.

webchick’s picture

If we're going to add alterability to these queries (I agree with catch this should be discussed in a separate issue), we already have a hook_query_alter(). No need to add a new hook IMO, just a tag on the query.

moshe weitzman’s picture

I spoke with catch on IRC. I'll now stop obstructing these patches for D7 since we have a plan for D8: use exportables (code+DB override, with persistent cache). I still can't mark the original patch RTBC without gagging.

catch’s picture

Title: Cache filter/format queries and allow contrib to alter them » Cache filter/format queries
Status: Needs review » Reviewed & tested by the community

Re-titling, I wrote the original patch, but none of the followups, and since this was already committed, but then reverted due to moshe's concerns, I'm going to move it back again.

dagmar’s picture

catch’s picture

Also it's #13 that's RTBC, the alter is in another issue now (thanks dagmar :).

Dries’s picture

Moshe: I don't like these patches either so I'd love to learn more about the exportables idea. Somehow I question that the exportables concept will make it _easier_ ... :)

webchick’s picture

I don't think this particular issue has anything to do with exportables, really. It's more about being able to serve Drupal pages directly from memcache without hitting the DB. The ability to *alter* this query so that instead of it grabbing a filter ID it grabs a machine name enables exportables, but that discussion has been moved to #903730: Missing drupal_alter() for text formats and filters.

dagmar’s picture

Well not just alter the query. Load text formats from code requires a drupal_alter too.

catch’s picture

The discussion with Moshe was that he wants a plan for sorting this out in D8, Dries also said somewhere he'd like an 'API' for it to encapsulate the pattern - for example making the storage pluggable/alterable so that contrib could swap in memcache while core could load directly from the db.

My view is that for D8, if we get exportables in, node types, text format configuration and user permissions (the only three queries run on nearly every page that aren't already cached) are good candidates. The storage pattern for exportables is this:

1. Defined in code.
2. Overwritten or added to in the database.
3. These merged and cached via cache_get() and cache_set()

If that pattern gets applied to these commonly requested configuration queries, then having to put each individual set of configuration into memcache won't be necessary.

For this patch on its own merits, please see the write up and mysqlsla output at http://drupal.org/node/898360#comment-3472754

sun’s picture

sun’s picture

#13 is still RTBC then and currently blocks #903730: Missing drupal_alter() for text formats and filters, as there is no clear target code to run a patch against.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

Status: Fixed » Closed (fixed)
Issue tags: -Performance

Automatically closed -- issue fixed for 2 weeks with no activity.