diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index eb81870..ff7a058 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -1707,48 +1707,36 @@ function taxonomy_field_presave($entity_type, $entity, $field, $instance, $langc
 }
 
 /**
- * Implements hook_field_insert().
+ * Implements hook_node_insert().
  */
-function taxonomy_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
+function taxonomy_node_insert($node) {
   // We maintain a denormalized table of term/node relationships, containing
   // only data for current, published nodes.
-  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node' && $entity->status) {
-    $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
-    foreach ($items as $item) {
-      $query->values(array(
-        'nid' => $entity->nid,
-        'tid' => $item['tid'],
-        'sticky' => $entity->sticky,
-        'created' => $entity->created,
-      ));
-    }
-    $query->execute();
-  }
-}
-
-/**
- * Implements hook_field_update().
- */
-function taxonomy_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
-  if (variable_get('taxonomy_maintain_index_table', TRUE) && $field['storage']['type'] == 'field_sql_storage' && $entity_type == 'node') {
-    $first_call = &drupal_static(__FUNCTION__, array());
-
-    // We don't maintain data for old revisions, so clear all previous values
-    // from the table. Since this hook runs once per field, per object, make
-    // sure we only wipe values once.
-    if (!isset($first_call[$entity->nid])) {
-      $first_call[$entity->nid] = FALSE;
-      db_delete('taxonomy_index')->condition('nid', $entity->nid)->execute();
+  if (variable_get('taxonomy_maintain_index_table', TRUE) && $node->status) {
+    // Collect all the terms.
+    $tid_all = array();
+    foreach (field_info_instances('node', $node->type) as $instance) {
+      $field_name = $instance['field_name'];
+      $field = field_info_field($field_name);
+      if ($field['module'] == 'taxonomy' && $field['storage']['type'] == 'field_sql_storage') {
+        foreach (field_available_languages('node', $field) as $langcode) {
+          if (!empty($node->{$field_name}[$langcode])) {
+            foreach ($node->{$field_name}[$langcode] as $item) {
+              $tid_all[$item['tid']] = $item['tid'];
+            }
+          }
+        }
+      }
     }
-    // Only save data to the table if the node is published.
-    if ($entity->status) {
-      $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created'));
-      foreach ($items as $item) {
+    // Insert index for all the terms.
+    if (!empty($tid_all)) {
+      $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created', ));
+      foreach ($tid_all as $tid) {
         $query->values(array(
-          'nid' => $entity->nid,
-          'tid' => $item['tid'],
-          'sticky' => $entity->sticky,
-          'created' => $entity->created,
+          'nid' => $node->nid,
+          'tid' => $tid,
+          'sticky' => $node->sticky,
+          'created' => $node->created,
         ));
       }
       $query->execute();
@@ -1757,6 +1745,14 @@ function taxonomy_field_update($entity_type, $entity, $field, $instance, $langco
 }
 
 /**
+ * Implements hook_node_update().
+ */
+function taxonomy_node_update($node) {
+  taxonomy_node_delete($node);
+  taxonomy_node_insert($node);
+}
+
+/**
  * Implements hook_node_delete().
  */
 function taxonomy_node_delete($node) {
diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test
index aa7cc2e..741d28b 100644
--- a/modules/taxonomy/taxonomy.test
+++ b/modules/taxonomy/taxonomy.test
@@ -829,6 +829,145 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
 }
 
 /**
+ * Tests for taxonomy term index.
+ */
+class TaxonomyTermIndexTestCase extends TaxonomyWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Taxonomy term index',
+      'description' => 'Test the index of tid to nid (taxonomy_index).',
+      'group' => 'Taxonomy',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('taxonomy');
+    $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
+    $this->drupalLogin($this->admin_user);
+    $this->vocabulary = $this->createVocabulary();
+
+    $this->field_name_1 = drupal_strtolower($this->randomName());
+    $this->field_1 = array(
+      'field_name' => $this->field_name_1,
+      'type' => 'taxonomy_term_reference',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    field_create_field($this->field_1);
+    $this->instance_1 = array(
+      'field_name' => $this->field_name_1,
+      'bundle' => 'article',
+      'entity_type' => 'node',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'default' => array(
+          'type' => 'taxonomy_term_reference_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance_1);
+
+    $this->field_name_2 = drupal_strtolower($this->randomName());
+    $this->field_2 = array(
+      'field_name' => $this->field_name_2,
+      'type' => 'taxonomy_term_reference',
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vocabulary' => $this->vocabulary->machine_name,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    field_create_field($this->field_2);
+    $this->instance_2 = array(
+      'field_name' => $this->field_name_2,
+      'bundle' => 'article',
+      'entity_type' => 'node',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'default' => array(
+          'type' => 'taxonomy_term_reference_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance_2);
+  }
+
+  /**
+   * Test index.
+   */
+  function testTaxonomyIndex() {
+    // Create terms in the vocabulary.
+    $term_1 = $this->createTerm($this->vocabulary);
+    $term_2 = $this->createTerm($this->vocabulary);
+
+    // Post an article.
+    $edit = array();
+    $langcode = LANGUAGE_NONE;
+    $edit["title"] = $this->randomName();
+    $edit["body[$langcode][0][value]"] = $this->randomName();
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_1->tid;
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_1->tid;
+    $this->drupalPost('node/add/article', $edit, t('Save'));
+
+    // Check that the term is indexed, and only once.
+    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed.'));
+
+    // Update the article to change one term.
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_2->tid;
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
+
+    // Check that both terms are indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 1 is indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed.'));
+
+    // Update the article again to change another term.
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_2->tid;
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
+
+    // Check that only one term is indexed.
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_1->tid,
+    ))->fetchField();
+    $this->assertEqual(0, $index_count, t('Term 1 is not indexed.'));
+    $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
+      ':nid' => $node->nid,
+      ':tid' => $term_2->tid,
+    ))->fetchField();
+    $this->assertEqual(1, $index_count, t('Term 2 is indexed.'));
+  }
+}
+
+/**
  * Test the taxonomy_term_load_multiple() function.
  */
 class TaxonomyLoadMultipleUnitTest extends TaxonomyWebTestCase {
