The nodereference module's formatters currently do a full node_load() on the target node, and create a link with l(). It then, conditionally, UNlinks that string with strip_tags(). Both of those are horribly inefficient, especially when using a nodereference field in a View. It can mean easily a half-dozen extra, needless queries for each record being listed.

The attached patch does two things to formatter function. First, it skips the node_load() in favor of a static-cached simple query against the node table. I've never seen a module modify a node title on load instead of on save (and if it did, it would be ignored in various places in core already), so the node_load() is not needed. It then builds the link only if necessary. Secondly, it introduces a 3rd formatter "nid only", which does no lookup at all. That is useful in a View (or simple node view) where you want to load the node reference field as a nid, for whatever reason, but won't be displaying it to the user. Getting the node's title is, therefore, a waste of time.

With this patch, I was able to cut the number of queries on a single page in half from ~150 to ~75, without breaking any other functionality. Sounds like a win. :-)

CommentFileSizeAuthor
no-node-load.patch1.46 KBCrell
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

there would be another option:
Create a handler for the nodereference field, which joins to another node table. So you could get the node title without doing any extra queries.

I agree that a node_load() isn't necessary to get the title. Views does in general no node_load() for fetching any field data.

moshe weitzman’s picture

this looks quite sane to me. +1

Crell’s picture

Well someone needs to RTBC this before it can sanely get in, and it can't be me. :-)

yched’s picture

Status: Needs review » Fixed

Committed a slightly modified version of the 'skip node_load' part. Thanks !

I left out the 'nid' formatter for now :
- It's still unclear to me how it is actually needed : you get the nid in $node->field_xxx[n]['nid'], so you can do your node_load from there. Do you really _need_ to display the raw nid in a view ?
- if it's used only for a few advanced tricks, I'm not sure we want it exposed to all the users.
I'm still open for discussion, though :-)

Marking as 'fixed' for now

Crell’s picture

Thanks yched!

I suppose there's use cases where you would want to expose just the NID, but the use case I was using it for is to support the tree-style display for a Views List. The Views Theme Wizard now supports Grouped and Tree-based list views (and a hook to add more). The Tree-based view is based on a simple "parent nid" (or some id and parent id) field, for which nodereference is the natural solution. So it never gets shown to the user; it's just used for the tree-grouping in the theming function.

I suppose it could also be called the "raw" formatter, since that's what it is. Sometimes all you want is the raw data.

yched’s picture

@fago, if you're listening : is this need for a raw nid format in any way related to the views fusion integration issues (which, er, I still did not really find some time to wrap my head around...)

fago’s picture

sry, 4 the late reply.
no views fusion doesn't need that nid field.

Crell’s picture

I still think a "Raw" option is important in general, but in particular here. There's plenty that can be done with a field that doesn't involve displaying it.

Anonymous’s picture

Status: Fixed » Closed (fixed)