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. :-)
Comment | File | Size | Author |
---|---|---|---|
no-node-load.patch | 1.46 KB | Crell |
Comments
Comment #1
fagothere 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.
Comment #2
moshe weitzman CreditAttribution: moshe weitzman commentedthis looks quite sane to me. +1
Comment #3
Crell CreditAttribution: Crell commentedWell someone needs to RTBC this before it can sanely get in, and it can't be me. :-)
Comment #4
yched CreditAttribution: yched commentedCommitted 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
Comment #5
Crell CreditAttribution: Crell commentedThanks 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.
Comment #6
yched CreditAttribution: yched commented@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...)
Comment #7
fagosry, 4 the late reply.
no views fusion doesn't need that nid field.
Comment #8
Crell CreditAttribution: Crell commentedI 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.
Comment #9
(not verified) CreditAttribution: commented