Say I have an nid (or a lot of them). Would it be faster to load the node to access get the title, or do the very simple db_query required to get the node title?
6 Answers
You said fastest.
If you can compromise two things, this should be the fastest one. Now, note that you have to compromise:
If you are only trying to get the node
title
, and if you are sure that there are no otherhook_node_load
implementations (basically module handlers that would alter the node load at the time they are loaded), you can skip using thenode_load()
ornode_load_multiple()
functions and go for this solution.When loading a node from the database, it's advised that you use a query tag to make sure that the user has access to those nodes. If you don't use any node access modules, you can go down for this solution.
With both above points in mind you can uses something like this:
function MYMODULE_node_get_title_fast(array $nids) {
$titles = &drupal_static(__FUNCTION__, array());
$return = array();
$unavailable = array();
foreach ($nids as $nid) {
// Lookup static cache of self.
if (array_key_exists($nid, $titles)) {
$return[$nid] = $titles[$nid];
}
else { // Set NULL, so unavailable nodes will have NULL as their return value.
$unavailable[$nid] = NULL;
}
}
if ($unavailable) {
$results = db_query("SELECT nid, title FROM {node} WHERE nid IN (:nids)", array(':nids' => array_keys($unavailable)))->fetchAllKeyed(0, 1);
if ($results) {
$return = $results + $unavailable;
$titles = $return + $titles;
}
}
return $return;
}
You can pass an array of node IDs, and the above function will return their titles without the overhead of node_load
, field_attach
, or entity_load
overheads. It also skips node access checks, so do not use this in sites that you want any sort of access restrictions.
Usage example:
$titles = MYMODULE_node_get_title_fast(array(256, 258, 54898));
You would return an array, with all given array values as keys, and the title as their value. NULL
if the node is unavailable.
-
Full disclosure: I have not tried this solution, but it answers the question the best. Commented Jun 8, 2016 at 23:13
Use node_load_multiple to get nodes with your set of nids.
From the documentation page:
This function should be used whenever you need to load more than one node from the database. Nodes are loaded into memory and will not require database access if loaded again during the same page request.
-
3This is the only correct answer. If you need performance, enable entitycache.– user49Commented Dec 16, 2015 at 5:55
the better way to do this is:
<?php
$node_title = node_load($nid)->title;
?>
and i think that if there is a way to do it with out direct query to DB. then you must go to that way.as in most cases these ways are perfect,easy and optimized.
Loading whole node data for just a title is overkill, if you apply entity_load() or node_load() it involved a bunch of joins to render the data from fields tables which obviously is not a good solution. I would rather suggest to apply
db_query("SELECT title from {node} where nid = :nid and status and status = :status" , array(':nid' => <Your nid>, ':status' => 1 ( //for published nodes)))
-
That's kind of what I was thinking. However, I wonder, where is the breakeven point? How many other fields to join before its better to use node_load? or is node_load almost always just a convenience, and if you want to do queries for performance there is no harm in that? Commented Dec 14, 2015 at 16:07
-
if all you need is title then no joins involved but if you need some data fields which are attached through fields api then you will need that number of joins. Commented Dec 14, 2015 at 16:10
-
Wrong, you are skipping
load
hooks. Usenode_load_multiple
.– user49Commented Dec 16, 2015 at 5:57
Also if you want get it by query use db_select With fetchField
$result = db_select('node', 'n')
->fields('title')
->condition('nid', $nid,'=')
->condition('status', 0,'>')
->execute()
->fetchField();
The Easiest way to get it using node_load function.very simple and clean ;)
$node=node_load($nid);
// So $node->title contatile title
Learn this useful function.
node_load($nid = NULL, $vid = NULL, $reset = FALSE)
Loads a node object from the database. Parameters
$nid: The node ID.
$vid: The revision ID.
$reset: Whether to reset the node_load_multiple cache.
Also if you want get fetchField by query use db_select
$result = db_select('node', 'n')
->fields('title')
->condition('nid', $nid,'=')
->condition('status', 0,'>')
->execute()
->fetchAssoc();
Also you can get it by db_query`
$result = db_query('SELECT n.nid, n.title, n.created
FROM {node} n WHERE n.nid = :nid', array(':uid' => $nid));
But you can try it by yourself speed test of getting one node with db_select
db_query
is very tiny.
Use this function for SELECT queries if it is just a simple query string. If the caller or other modules need to change the query, use db_select() instead.
-
db_select
is much slower thandb_query
(since we are in a performance question). Neither is appropriate. Also you recommended printing unescaped user data which is a security hole!– user49Commented Dec 16, 2015 at 5:53 -
@chx printing was a example that he found title exist there, also if you want fast way you can write raw Php code!!! ** printing unescaped user data which is a security hole** is not truth, title fetched from database , this thing you speak about is in writing in database not reading form it !!!! and if you look at question and comments you can see exact sentence about how speed performance. and Finally I test it by myself, the different speed between getting node with node_load and db_query is less than 0.001ms.– YuseferiCommented Dec 16, 2015 at 6:07
-
There are many modules in contrib that implement
node_load
hook, so depending on the modules you use, the difference can be different. I'm also agreeing with what chx mentioned about db_select vs db_query. db_select() is a lot slower, and I have found myself preferring db_query more and more.– AKSCommented Dec 16, 2015 at 6:36 -
-
Cannot be checked with another function, or with a previous
db_query
if there are hooks affecting load? Is that stored somewhere besides the pure PHP code?– CesarCommented Dec 16, 2015 at 7:14
load
hooks for example. Usenode_load_multiple
and hope someone enabled entitycache.