8

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?

1
  • 2
    Every answer talking to the database is incorrect as they skip the load hooks for example. Use node_load_multiple and hope someone enabled entitycache.
    – user49
    Commented Dec 16, 2015 at 5:54

6 Answers 6

7

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 other hook_node_load implementations (basically module handlers that would alter the node load at the time they are loaded), you can skip using the node_load() or node_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.

1
  • Full disclosure: I have not tried this solution, but it answers the question the best. Commented Jun 8, 2016 at 23:13
5

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.

1
  • 3
    This is the only correct answer. If you need performance, enable entitycache.
    – user49
    Commented Dec 16, 2015 at 5:55
3

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.

2

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)))

3
  • 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.
    – Shabir A.
    Commented Dec 14, 2015 at 16:10
  • Wrong, you are skipping load hooks. Use node_load_multiple.
    – user49
    Commented Dec 16, 2015 at 5:57
0

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();

0
0

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.

7
  • db_select is much slower than db_query (since we are in a performance question). Neither is appropriate. Also you recommended printing unescaped user data which is a security hole!
    – user49
    Commented 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.
    – Yuseferi
    Commented 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.
    – AKS
    Commented Dec 16, 2015 at 6:36
  • @AyeshK ok, provide you benchmark here.
    – Yuseferi
    Commented Dec 16, 2015 at 7:11
  • Cannot be checked with another function, or with a previous db_queryif there are hooks affecting load? Is that stored somewhere besides the pure PHP code?
    – Cesar
    Commented Dec 16, 2015 at 7:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.