Problem/Motivation

When a view is saved, views_invalidate_cache() is called, resulting in an entire re-build of the views cache being required. On a site with a lot of views, this process can take 30+ seconds and renders the entire site unusable until it has been rebuilt.

Proposed resolution

In the case of saving a view, I would have thought just clearing the single view from the cache and then clearing the page/block/menu cache would be sufficient. We shouldn't need to rebuild cache of the entire views data or any other view, as saving a specific view wont affect any of those.

Members fund testing for the Drupal project. Drupal Association Learn more

Comments

andrewbelcher’s picture

Status: Active » Needs review
FileSize
2.12 KB
PASSED: [[SimpleTest]]: [MySQL] 1,652 pass(es). View

I don't really know views' internals very well so I don't know if this would have other problems, but I've attached a patch that I think may resolve the issue by allowing a 'partial' call to views_invalidate_cache()...

Anybody’s picture

I can confirm that this problem still exists. Saving a view requires up to 16 GB (!!) of memory on my page. This is not really nice ;)

andyg5000’s picture

Issue summary: View changes

In our instance, variable_set('menu_rebuild_needed', TRUE); that's called in views_invalidate_cache() is the killer and isn't addressed in the patch. Looking for a solution other than commenting that out as discussed in #2263557: Slow performance when saving views which I closed as a dupe of this.

david_garcia’s picture

The complete menu rebuild is also an issue. But it is the only way to get changes in views displays that have a path (such as pages) to take inmediate effect.

Maybe a quick solution would be to only invalidate the menu cache if:

- Any of the existing views is of type "page" (or any display that uses a path) and the path has changed.
- A display of the current view has been added/removed, and it uses paths.

This last solutions does not look that bad, as it will only invalidate the menu cache if anything in the view has changed that afects it.

Shane Birley’s picture

Is there anything I can do to help with this issue? I have a few sites where the saving of a view takes about 200 years. I didn't realize that each save forces such a clearing of any cache systems.

joelpittet’s picture

@Shane Birley can you confirm this patch saves a few years?

This patch looks like it would be very useful. Is there anything missing where it would miss things that need to be cleared?

joelpittet’s picture

Issue tags: +Performance
joelpittet’s picture

A rough performance test with just devel, saving a view that didn't change changed (opened the title and hit ok to get the save button).

Xdebug was turned off:

Without patch
  - Executed 3215 queries in 1516.48 ms. 
    Page execution time was 10013.1 ms. 
    Memory used at: devel_boot()=2.39 MB, devel_shutdown()=118.12 MB, PHP peak=148.75 MB.
  - Executed 3211 queries in 1548.17 ms.
    Page execution time was 10034.37 ms. 
    Memory used at: devel_boot()=2.39 MB, devel_shutdown()=118.17 MB, PHP peak=148.25 MB.

With patch
  - Executed 3314 queries in 1610.93 ms. 
    Page execution time was 9338.66 ms. 
    Memory used at: devel_boot()=2.39 MB, devel_shutdown()=122.71 MB, PHP peak=153.75 MB.
  - Executed 3318 queries in 1605.3 ms. 
    Page execution time was 9080.62 ms. 
    Memory used at: devel_boot()=2.39 MB, devel_shutdown()=122.61 MB, PHP peak=153.5 MB.

And to the point about variable_set('menu_rebuild_needed', TRUE); Just disabling that with the patch and no xdebug:

  - Executed 65 queries in 27.72 ms. 
     Page execution time was 528.3 ms. 
     Memory used at: devel_boot()=2.32 MB, devel_shutdown()=46.79 MB, PHP peak=47.25 MB.
  - Executed 69 queries in 32.64 ms. 
     Page execution time was 547.86 ms. 
     Memory used at: devel_boot()=2.32 MB, devel_shutdown()=46.88 MB, PHP peak=47.5 MB.

Summary

This patch saves me roughly ~700ms-1s. Avoiding the menu rebuild saved ~8.5 seconds from that.

So the bigger win would go to avoiding the menu rebuild. Are there any conditions we could check like (path changed on view, or other things that would require a menu rebuild)?

Menu path doesn't change often so this could be huge.

or work on core menu rebuilding not taking so long:)

torgosPizza’s picture

@joelpittet: Regarding the rebuilding of menu items, give #1978176: Build menu_tree without loading so many objects a glance. There was a patch there that helped me a LOT but it still needs some work.

joelpittet’s picture

@torgosPizza I'm on that issue, a bit worried about #1978176-68: Build menu_tree without loading so many objects #68 David R's comment about security.

joelpittet’s picture

Thanks for pointing at it again though. I should really take a stab to see my savings!

joelpittet’s picture

Using the patch @torgosPizza mentioned in #9 with xdebug off and doing the same quick devel page test of saving a view on no changes and with the patch applied.

Run #1
Executed 3689 queries in 1830.8 ms. 
Page execution time was 11346.3 ms. 
Memory used at: devel_boot()=2.53 MB, devel_shutdown()=131.54 MB, PHP peak=169.5 MB.
Run #2
Executed 3314 queries in 1573.32 ms. 
Page execution time was 9163.66 ms. Memory used at: devel_boot()=2.43 MB, devel_shutdown()=123.01 MB, PHP peak=159.25 MB.

The page execution time was roughly the same. So unfortunately no gain was made with that other issue's patch for me.

torgosPizza’s picture

Yeah, the earlier one was the one that actually got me decent results (comment #32). I guess it's one of those YMMV situations!

sylus’s picture

I understand that it is only the menu_rebuild that yields drastic results but as for the original patch and issue itself I think it does make sense to only invalidate the cache for a single view. Possible to RTBC this patch and leave the rest to #1978176: Build menu_tree without loading so many objects?

joelpittet’s picture

Status: Needs review » Reviewed & tested by the community

I'm going to RTBC this because I've been using it for quite some time and it was helping me out:)

joelpittet’s picture

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

Actually, with the latest dev it needs a re-roll, then RTBC:)

joelpittet’s picture

Re-roll of #1

Status: Needs review » Needs work

The last submitted patch, 17: saving_a_view_causes-2071607-17.patch, failed testing.

Anybody’s picture

Mhm any idea why the tests fail? I can confirm it was RTBC and working before...

sylus’s picture

Status: Needs work » Needs review

Re-triggering

Status: Needs review » Needs work

The last submitted patch, 17: saving_a_view_causes-2071607-17.patch, failed testing.

The last submitted patch, 17: saving_a_view_causes-2071607-17.patch, failed testing.

joelpittet’s picture

The tests are expecting more is cleared than are, or we need to clear some other cid as well.

torgosPizza’s picture

This patch helped us, as we've been dealing with downtime every time I save one particular View. For me it's RTBC but to @joelpittet's comment I'd like to see what we can do to get the tests to turn green.

Anybody’s picture

+1 for #24. In case the view display has a menu entry perhaps the menu cache also has to be cleared? Might that cause the tests to fail?

The last submitted patch, 17: saving_a_view_causes-2071607-17.patch, failed testing.

Anybody’s picture

Priority: Normal » Major

I've just been running into a new downtime again because this patch was not commited... bad trouble with the customer. For large sites this is a real problem causing downtimes so I'm now pushing the priority. I also retriggered to test and will have a look at the reasons why it still fails afterwards.

joseph.olstad’s picture

we're also using this patch #17 because it's such a huge improvement on save speeds, (despite the test failures) , not sure why the test failures.

joelpittet’s picture

Status: Needs work » Needs review
FileSize
2.39 KB

This will solve the test failures but I'm not sure what caches need to be cleared and which ones are fine to leave on save and delete?

Anybody’s picture

Thank you joelpittet, the patch looks good so far. But it should also consider to only set

variable_set('menu_rebuild_needed', TRUE);

if a menu related setting has been changes or the view display type is menu related (like "page"). Otherwise the menu rebuild is extremely painful and expensive. It also locks the database until the rebuild is done.

joelpittet’s picture

Status: Needs review » Needs work

@Anybody, that sounds like a nice addition but maybe a scope creep on this issue. There is no context provided to that function to help tell if the view has a menu or not.

The bigger question to get this in is "How do we know we've cleared enough from cache_views"? There could be a contrib that potentially relies on that clear to function which could be a blocker for this.

Anybody’s picture

@joelpittet: Thank you for your quick reply. You are right that one main question is "How do we know we've cleared enough from cache_views"? but I'm sadly not able to answer that question. Should we perhaps contact a views maintainer for that?

But furthermore I think that the menu rebuild point is not a nice addition but a very important point. On large websites that is a very huge problem and as far as we can tell even the largest problem of all at this point. Currently we even have to comment out that line on pages with > 1 mio nodes. And that page uses panels etc. to include views instead of views pages. I think that menu related views (=views page display type) are at least < 50% of all views display types used.
But of course we may not introduce wrong or missing functionality here but I think that function call has to be much more granular perhaps at a very different point int the views display definition, perhaps using a hook?
If you ask me, that call should have never been placed at that point.

So how can we go on and who can we ask best?

If you agree I'd like to place these two last points on the agenda to finally fix this old issue.

joelpittet’s picture

@Anybody, the menu_rebuild_needed point could be it's own issue.

Not sure who to ask.