diff --git a/schema.drush.inc b/schema.drush.inc
index be78ed9..a85d234 100644
--- a/schema.drush.inc
+++ b/schema.drush.inc
@@ -98,7 +98,7 @@ function drush_schema_compare_validate($type) {
 function drush_schema_compare($type) {
 
   // Get the defined database schema.
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
 
   // Compare it with the actual database schema.
   $comparison = schema_compare_schemas($schema);
diff --git a/schema.install b/schema.install
index d5eab92..7274e97 100755
--- a/schema.install
+++ b/schema.install
@@ -17,7 +17,7 @@ function schema_requirements($phase) {
   $reqs = array();
   $t = get_t();
   if ($phase == 'runtime' && variable_get('schema_status_report', TRUE)) {
-    $schema = drupal_get_schema(NULL, TRUE);
+    $schema = schema_get_schema();
     $info = schema_compare_schemas($schema);
     // make sure these are defined in increasing-severity order
     $checks = array(
diff --git a/schema.module b/schema.module
index ad1a5cc..ecc3788 100755
--- a/schema.module
+++ b/schema.module
@@ -645,3 +645,31 @@ function field_schema_field_type_map_alter(array &$map, DatabaseSchema $schema,
     }
   }
 }
+
+/**
+ * A copy of drupal_get_schema() optimized for schema module use.
+ */
+function schema_get_schema() {
+  $schema = &drupal_static(__FUNCTION__);
+
+  if (!isset($schema)) {
+    $schema = array();
+    module_load_all_includes('install');
+
+    // Invoke hook_schema for all modules.
+    foreach (module_implements('schema') as $module) {
+      // Cast the result of hook_schema() to an array, as a NULL return value
+      // would cause array_merge() to set the $schema variable to NULL as well.
+      // That would break modules which use $schema further down the line.
+      $current = (array) module_invoke($module, 'schema');
+      // Set 'module' and 'name' keys for each table. Keep descriptions,
+      // they are slow but very useful for this module.
+      _drupal_schema_initialize($current, $module, FALSE);
+      $schema = array_merge($schema, $current);
+    }
+
+    drupal_alter('schema', $schema);
+  }
+
+  return $schema;
+}
diff --git a/schema.pages.inc b/schema.pages.inc
index 73f238e..dfbb596 100644
--- a/schema.pages.inc
+++ b/schema.pages.inc
@@ -28,7 +28,7 @@ function schema_compare() {
     'missing' => t('Tables in the schema that are not present in the database.'),
   );
 
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
   $info = schema_compare_schemas($schema);
 
   // The info array is keyed by state (same/different/missing/extra/warn). For missing,
@@ -124,7 +124,7 @@ function schema_compare() {
 function schema_describe() {
   $build = array();
 
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
   ksort($schema);
   $row_hdrs = array(t('Name'), t('Type[:Size]'), t('Null?'), t('Default'));
 
@@ -196,7 +196,7 @@ function schema_inspect() {
   $mods = module_list();
   sort($mods);
   $mods = array_flip($mods);
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
   $inspect = schema_dbobject()->inspect();
   foreach ($inspect as $name => $table) {
     $module = isset($schema[$name]['module']) ? $schema[$name]['module'] : 'Unknown';
@@ -224,7 +224,7 @@ function schema_inspect() {
  * "SQL" menu callback.
  */
 function schema_sql($engine = NULL) {
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
   $connection = Database::getConnection();
   $sql = '';
   foreach ($schema as $name => $table) {
@@ -251,7 +251,7 @@ function schema_sql($engine = NULL) {
  * as you need.
  */
 function schema_show() {
-  $schema = drupal_get_schema(NULL, TRUE);
+  $schema = schema_get_schema();
   $show = var_export($schema, 1);
 
   return "<textarea style=\"width:100%\" rows=\"30\">$show</textarea>";
diff --git a/tests/schema_regression.test b/tests/schema_regression.test
index c855c1b..0a945c9 100644
--- a/tests/schema_regression.test
+++ b/tests/schema_regression.test
@@ -49,8 +49,8 @@ class SchemaRegressionTest extends DrupalWebTestCase {
     $this->assertTrue(isset($fields['destid']), 'Column destid exists.');
 
     // Inspect the table by using schema_compare().
-    $schema = drupal_get_schema('schema_test_1');
-    $comparison = schema_compare_table($schema);
+    $schema = schema_get_schema();
+    $comparison = schema_compare_table($schema['schema_test_1']);
     $this->assertEqual($comparison['status'], 'different', 'Table does not match its schema.');
   }
 }
