This is the last query required to fully bootstrap Drupal then render a page in core. All the others can be more-or-less cleanly eliminated via settings or pluggable includes.

Executed 0 queries in 0 ms. Queries exceeding 5 ms are highlighted.

Comments

moshe weitzman’s picture

I just can't stomach using persistent caches as a mechanism to remove queries from page delivery. This is a single table, fully indexed query. It doesn't need any speeding up via cache.

I'm gonna leave this as needs review since I might be outnumbered here. Opinions welcome.

catch’s picture

This is less about speeding up, and more about allowing pages to be served only from apache/php + memcache - so that you can scale sideways with apache for auth users a very long time before you need to do the same with MySQL. I hadn't really thought about it like this until Narayan explained what had happened with load testing - this isn't really paraphrasing but I hope the gist is the same:

When most sites get bigger, you split a single server into web server and database server (let's assume you added memcache already).

Once you have a separate database server, it might be able to handle more requests than your apache server, so to remove that bottleneck you add a load balancer and an extra web head.

Lets say you keep adding webheads - eventually, the load on the db server is going to increase to the point where it's the bottleneck again. At that point, the only choice you have is adding a read-only db slave or caching more aggressively.

In D6, you can get to this situation pretty fast, since there'll be unindexed queries, and a high volume of small ones (100-300 per page isn't rare) on pretty much any site. In D7, let's assume mongodb, entitycache, pathcache.module too, yo might have 5-20 MySQL queries on a page, all of them small indexed ones. While MySQL is going to have low load for a lot longer,, it's still going to be the one point in the infrastructure where you can't simply add an extra server to add more requests - additional memcache and web servers are trivial to set up compared to replication and redirecting queries to slaves. Not only that, but Drupal core has relatively few queries which are designated as slave safe, so if the bottleneck ends up being the sheer number of requests served, then the normal use for a db slave (handing off long running queries) is less useful. For example this cache would be cleared at the exact same moment as a menu_rebuild(), however with MySQL replication there could be a five or ten minute delay - so the query isn't slave safe.

So while I agree the individual query is trivial, it's not going to make things measurably faster in itself etc, I do think there's value to doing these direct swaps at least where they're simple to implement like this (i.e. we already have per-page menu caches and there's already cache invalidation logic which works in this case).

chx’s picture

Status: Needs review » Reviewed & tested by the community

This is a no-brainer. Nothing can beat cache_get once it's out of MySQL. Free your mind. SQL is the slowest possible cache.

pwolanin’s picture

So, basically this cache entry shoudl only be invalidated at menu rebuild?

chx’s picture

When else does it change?

pwolanin’s picture

It does not change otherwise as far as I know - so basically it's just when we clear this entire cache table?

chx’s picture

Yes.

sun’s picture

local_tasks.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, local_tasks.patch, failed testing.

sun’s picture

Title: Cache the MySQL query in menu_local_tasks() » Cache the query in menu_local_tasks()
Category: bug » task
Status: Needs work » Needs review
Issue tags: +Performance
StatusFileSize
new1.35 KB

Re-rolled against HEAD.

marcingy’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +Needs backport to D7
StatusFileSize
new1.18 KB

Needs to be fixed in d8 first

Status: Needs review » Needs work

The last submitted patch, cache-menu-local-task-805236-11.patch, failed testing.

marcingy’s picture

Status: Needs work » Needs review

Looks like a bot issue.

marcingy’s picture

Status: Needs review » Needs work

The last submitted patch, cache-menu-local-task-805236-11.patch, failed testing.

marcingy’s picture

Status: Needs work » Needs review
Issue tags: +Performance, +Needs backport to D7
marcingy’s picture

StatusFileSize
new1.18 KB
Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch, cache-menu-local-task-805236-11.patch, failed testing.

The last submitted patch, cache-menu-local-task-805236-11.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review

I was part of the drupal office hours and I determined if this patch is still relevant.

First I retested the patch by klicking the re-test button. The result was that the patch test failed. Following the instructions on this site :http://core.drupalofficehours.org/task/762, I should try to reproduce this problem on drupal 8.

I`m not sure how to reproduce the problem.

Is this problem still relevant or should this issue be closed?

merrillholt’s picture

local_tasks.patch queued for re-testing.

merrillholt’s picture

Assigned: Unassigned » merrillholt
StatusFileSize
new1.17 KB

Converted the patch to Drupal 8 cache calls.

marcingy’s picture

Status: Needs review » Needs work

A cid is created but never used

$cid = 'local_tasks:' . $router_item['tab_root'];
if ($cached  = cache()->get('menu')) {

I assume it should be

$cid = 'local_tasks:' . $router_item['tab_root'];
if ($cached  = cache()->get($cid)) {
merrillholt’s picture

StatusFileSize
new1.17 KB

Reworked the arguments to the get and set and debugged to verify that the caching is occurring with repeated calls.
The comments in CacheBackendinterface.php still refer to the old cache_get() and cache_set().

berdir’s picture

Looking at the old patch, I think what this actually should do is cache('menu')->get($cid).

geerlingguy’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, cache-menu-local-task-805236-13.patch, failed testing.

merrillholt’s picture

Status: Needs work » Needs review
StatusFileSize
new1.18 KB

Updated with comment by Berdir. Ran all tests with and without the patch and compared the results. The only diff from the test outputs are:
< State system upgrade test 44 passes, 0 fails, and 0 exceptions
---
> State system upgrade test 42 passes, 0 fails, and 0 exceptions

Note that there are failures and exceptions with a complete test run without the patch (and these are identical with the patch);

Filter module filters 214 passes, 1 fail, and 0 exceptions
OpenID helper functions 43 passes, 2 fails, and 0 exceptions
Sort: Date 20 passes, 4 fails, and 0 exceptions

Entity Test Translation UI 68 passes, 0 fails, and 22 exceptions
Node translation UI 135 passes, 0 fails, and 18 exceptions
Taxonomy term translation UI 99 passes, 0 fails, and 22 exceptions

berdir’s picture

Status: Needs review » Needs work

@merrillholt: There is no need to do complete manual test run, that's what the testbots are for. It is usually enough to just run the relevant/failing tests.

+++ b/core/includes/menu.incundefined
@@ -1894,13 +1894,20 @@ function menu_local_tasks($level = 0) {
+      cache('menu')->set($cid,$result);

Missing a space after the ,

merrillholt’s picture

Status: Needs work » Needs review
StatusFileSize
new1.18 KB

added missing space.

yesct’s picture

ekl1773’s picture

StatusFileSize
new1.2 KB

Rerolled to catch up with HEAD. Also reverted to comment # naming convention.

berdir’s picture

Version: 8.x-dev » 7.x-dev
Status: Needs review » Needs work

This will work differently in 8.x, just hasn't been completely removed yet, the LocalTask(Plugin?)Manager already has caching built in for what he does.

Moving back to 7.x, setting to needs work, an older patch probably still applies, but let's re-upload that one for clarity.

star-szr’s picture

Assigned: merrillholt » Unassigned
Issue tags: +Novice

Thanks @Berdir! Tagging Novice to find the most recent patch on this issue that doesn't have 'core/' in the patch header (Dreditor will help!) and re-upload it.

Patch header that includes core/:

diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 47e1103..caacbdb 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -2052,13 +2052,20 @@ function menu_local_tasks($level = 0) {
ekl1773’s picture

Status: Needs work » Needs review
StatusFileSize
new1.18 KB

#17, June 30, 2011- header is as follows, re-uploading now.

diff --git a/includes/menu.inc b/includes/menu.inc
index 3a376f2..4053e8e 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -1831,13 +1831,21 @@ function menu_local_tasks($level = 0)
parthipanramesh’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

Works fine. Thank you!

David_Rothstein’s picture

Status: Reviewed & tested by the community » Fixed

Like Moshe in #1, I'm pretty skeptical of this... but there haven't been any other complaints in the past 3 years, so I guess we should go with it.

Committed to 7.x - thanks! http://drupalcode.org/project/drupal.git/commit/aa6235c

Status: Fixed » Closed (fixed)

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