diff --git a/apachesolr.module b/apachesolr.module
index 4616d36..032094b 100644
--- a/apachesolr.module
+++ b/apachesolr.module
@@ -469,12 +469,32 @@ function apachesolr_document_id($id, $entity = 'node') {
  * Implements hook_user().
  *
  * Mark nodes as needing re-indexing if the author name changes.
+ *
+ * @see http://drupal.org/node/592522
+ *   Performance issue with Mysql
+ * @see http://api.drupal.org/api/drupal/includes--database--database.inc/function/db_update/7#comment-15459
+ *   To know why PDO in drupal does not support UPDATE and JOIN at once.
  */
 function apachesolr_user_update(&$edit, $account, $category) {
   if (isset($edit['name']) && $account->name != $edit['name']) {
-    // TODO: performance issue. see http://drupal.org/node/592522
-    $nid_query = db_select('node')->fields('node', array('nid'))->where("uid = :uid", array(':uid' => $account->uid));
-    db_update('apachesolr_search_node')->condition('nid', $nid_query, 'IN')->fields(array('changed' => REQUEST_TIME))->execute();
+    switch (db_driver()) {
+      case 'mysql' :
+        $query = "UPDATE {apachesolr_search_node} asn
+          INNER JOIN {node} n ON asn.nid = n.nid SET asn.changed = :changed
+          WHERE n.uid = :uid";
+        $result = db_query($query, array(':changed' => REQUEST_TIME,
+          ':uid' => $account->uid,
+        ));
+        break;
+      default :
+        $nids = db_select('node')
+          ->fields('node', array('nid'))
+          ->where("uid = :uid", array(':uid' => $account->uid));
+        $update = db_update('apachesolr_search_node')
+          ->condition('nid', $nids, 'IN')
+          ->fields(array('changed' => REQUEST_TIME))
+          ->execute();
+    }
   }
 }
 
@@ -482,11 +502,31 @@ function apachesolr_user_update(&$edit, $account, $category) {
  * Implements hook_taxonomy().
  *
  * Mark nodes as needing re-indexing if a term name changes.
+ *
+ * @see http://drupal.org/node/592522
+ *   Performance issue with Mysql
+ * @see http://api.drupal.org/api/drupal/includes--database--database.inc/function/db_update/7#comment-15459
+ *   To know why PDO in drupal does not support UPDATE and JOIN at once.
  */
 function apachesolr_taxonomy_term_update($term) {
-  // TODO: performance issue. see http://drupal.org/node/592522
-  $nid_query = db_select('taxonomy_index')->fields('taxonomy_index', array('nid'))->where("tid = :tid", array(':tid' => $term->tid));
-  db_update('apachesolr_search_node')->condition('nid', $nid_query, 'IN')->fields(array('changed' => REQUEST_TIME))->execute();
+  switch (db_driver()) {
+    case 'mysql' :
+      $query = "UPDATE {apachesolr_search_node} asn
+        INNER JOIN {term_node} tn ON asn.nid = n.nid SET asn.changed = :changed
+        WHERE tn.tid = :tid";
+      $result = db_query($query, array(':changed' => REQUEST_TIME,
+        ':tid' => $term->tid,
+      ));
+      break;
+    default :
+      $nids = db_select('taxonomy_index')
+        ->fields('taxonomy_index', array('nid'))
+        ->where("tid = :tid", array(':tid' => $term->tid));
+      $update = db_update('apachesolr_search_node')
+        ->condition('nid', $nids, 'IN')
+        ->fields(array('changed' => REQUEST_TIME))
+        ->execute();
+  }
   // TODO: the rest, such as term deletion.
 }
 
@@ -536,7 +576,10 @@ function apachesolr_comment_unpublish($comment) {
  * Mark one node as needing re-indexing.
  */
 function apachesolr_mark_node($nid) {
-  db_update('apachesolr_search_node')->condition('nid', $nid)->fields(array('changed' => REQUEST_TIME))->execute();
+  db_update('apachesolr_search_node')
+    ->condition('nid', $nid)
+    ->fields(array('changed' => REQUEST_TIME))
+    ->execute();
 }
 
 /**
@@ -548,12 +591,34 @@ function apachesolr_node_type_delete($info) {
 
 /**
  * Implements of hook_node_type_update().
+ *
+ * @see http://drupal.org/node/592522
+ *   Performance issue with Mysql
+ * @see http://api.drupal.org/api/drupal/includes--database--database.inc/function/db_update/7#comment-15459
+ *   To know why PDO in drupal does not support UPDATE and JOIN at once.
  */
 function apachesolr_node_type_update($info) {
   if (!empty($info->old_type) && $info->old_type != $info->type) {
     // We cannot be sure we are going before or after node module.
-    $nid = db_select('node')->fields('node', array('nid'))->where("type = :new OR type = :old", array(':new' => $info->type, ':old' => $info->old_type));
-    db_update('apachesolr_search_node')->condition('nid', $nid, 'IN')->fields(array('changed' => REQUEST_TIME))->execute();
+    switch (db_driver()) {
+      case 'mysql' :
+        $query = "UPDATE {apachesolr_search_node} asn
+          INNER JOIN {node} n ON asn.nid = n.nid SET asn.changed = :changed
+          WHERE (n.type = :type OR n.type = :old_type)";
+        $result = db_query($query, array(':changed' => REQUEST_TIME,
+          ':type' => $info->type,
+          ':old_type' => $info->old_type,
+        ));
+        break;
+      default :
+        $nids = db_select('node')
+          ->fields('node', array('nid'))
+          ->where("type = :new OR type = :old", array(':new' => $info->type, ':old' => $info->old_type));
+        $update = db_update('apachesolr_search_node')
+          ->condition('nid', $nids, 'IN')
+          ->fields(array('changed' => REQUEST_TIME))
+          ->execute();
+    }
   }
 }
 
@@ -564,13 +629,16 @@ function apachesolr_index_status($namespace) {
   $excluded_types = apachesolr_get_excluded_types($namespace);
   list($last_change, $last_nid) = apachesolr_get_last_change($namespace);
 
-  $query = db_select('apachesolr_search_node', 'asn')->condition('asn.status', 1);
+  $query = db_select('apachesolr_search_node', 'asn')
+    ->condition('asn.status', 1);
   apachesolr_query_add_excluded_types($query, $excluded_types);
   $total = $query->countQuery()->execute()->fetchField();
 
   $query = db_select('apachesolr_search_node', 'asn')
     ->condition('asn.status', 1)
-    ->condition(db_or()->condition('asn.changed', $last_change, '>')->condition(db_and()->condition('asn.changed', $last_change)->condition('asn.nid', $last_nid, '>')));
+    ->condition(db_or()->condition('asn.changed', $last_change, '>')
+    ->condition(db_and()->condition('asn.changed', $last_change)
+    ->condition('asn.nid', $last_nid, '>')));
   apachesolr_query_add_excluded_types($query, $excluded_types);
   $remaining = $query->countQuery()->execute()->fetchField();
 
@@ -609,10 +677,22 @@ function apachesolr_clear_last_index($namespace = '') {
  */
 function apachesolr_rebuild_index_table($type = NULL) {
   if (isset($type)) {
-    $sel_query = db_select('node')
-      ->fields('node', array('nid'))
-      ->condition('type', $type);
-    db_delete('apachesolr_search_node')->condition('nid', $sel_query, 'IN')->execute();
+    switch (db_driver()) {
+      case 'mysql' :
+        $query = "DELETE FROM {apachesolr_search_node}
+          USING {apachesolr_search_node} asn
+          INNER JOIN {node} n ON asn.nid = n.nid
+          WHERE n.type = :type";
+        $result = db_query($query, array(':type' => $info->type));
+        break;
+      default :
+        $nids = db_select('node')
+          ->fields('node', array('nid'))
+          ->condition('type', $type);
+        db_delete('apachesolr_search_node')
+          ->condition('nid', $nids, 'IN')
+          ->execute();
+    }
 
     // Populate table
     $sel_query = db_select('node')
@@ -620,12 +700,14 @@ function apachesolr_rebuild_index_table($type = NULL) {
       ->condition('type', $type);
     $sel_query->addExpression(REQUEST_TIME, 'changed');
 
-    db_insert('apachesolr_search_node')->fields(array('nid', 'status', 'changed'))
+    db_insert('apachesolr_search_node')
+      ->fields(array('nid', 'status', 'changed'))
       ->from($sel_query)
       ->execute();
   }
   else {
-    db_delete('apachesolr_search_node')->execute();
+    db_delete('apachesolr_search_node')
+      ->execute();
     // Populate table
     $sel_query = db_select('node', 'n')
       ->fields('n', array('nid', 'status'));
@@ -640,12 +722,16 @@ function apachesolr_rebuild_index_table($type = NULL) {
       $sel_query->addExpression('GREATEST(n.created, n.changed)', 'changed');
     }
 
-    db_insert('apachesolr_search_node')->fields($insert_fields)
+    db_insert('apachesolr_search_node')
+      ->fields($insert_fields)
       ->from($sel_query)
       ->execute();
 
     // Make sure no nodes end up with a timestamp that's in the future.
-    db_update('apachesolr_search_node')->condition('changed', REQUEST_TIME, '>')->fields(array('changed' => REQUEST_TIME))->execute();
+    db_update('apachesolr_search_node')
+      ->condition('changed', REQUEST_TIME, '>')
+      ->fields(array('changed' => REQUEST_TIME))
+      ->execute();
     apachesolr_clear_last_index();
   }
   cache_clear_all('*', 'cache_apachesolr', TRUE);
