diff --git src/wp-includes/class-wp-term-query.php src/wp-includes/class-wp-term-query.php
index 2f3da47301..c1c4a2d29d 100644
--- src/wp-includes/class-wp-term-query.php
+++ src/wp-includes/class-wp-term-query.php
@@ -585,32 +585,18 @@ class WP_Term_Query {
 
 		$selects = array();
 		switch ( $args['fields'] ) {
-			case 'all':
-			case 'all_with_object_id' :
-			case 'tt_ids' :
-			case 'slugs' :
-				$selects = array( 't.*', 'tt.*' );
-				if ( 'all_with_object_id' === $args['fields'] && ! empty( $args['object_ids'] ) ) {
-					$selects[] = 'tr.object_id';
-				}
-				break;
-			case 'ids':
-			case 'id=>parent':
-				$selects = array( 't.term_id', 'tt.parent', 'tt.count', 'tt.taxonomy' );
-				break;
-			case 'names':
-				$selects = array( 't.term_id', 'tt.parent', 'tt.count', 't.name', 'tt.taxonomy' );
-				break;
 			case 'count':
 				$orderby = '';
 				$order = '';
 				$selects = array( 'COUNT(*)' );
 				break;
-			case 'id=>name':
-				$selects = array( 't.term_id', 't.name', 'tt.count', 'tt.taxonomy' );
+
+			case 'all_with_object_id' :
+				$selects = array( 't.term_id', 'tr.object_id' );
 				break;
-			case 'id=>slug':
-				$selects = array( 't.term_id', 't.slug', 'tt.count', 'tt.taxonomy' );
+
+			default:
+				$selects = array( 't.term_id' );
 				break;
 		}
 
@@ -673,41 +659,54 @@ class WP_Term_Query {
 		$this->request = "{$this->sql_clauses['select']} {$this->sql_clauses['from']} {$where} {$this->sql_clauses['orderby']} {$this->sql_clauses['limits']}";
 
 		// $args can be anything. Only use the args defined in defaults to compute the key.
-		$key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) ) ) . serialize( $taxonomies ) . $this->request );
+		$_args = wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) );
+		if ( 'count' !== $_fields && 'all_with_object_id' !== $_fields ) {
+			unset( $_args['fields'] );
+		}
+		$key = md5( serialize( $_args ) . $this->request );
+
 		$last_changed = wp_cache_get_last_changed( 'terms' );
 		$cache_key = "get_terms:$key:$last_changed";
 		$cache = wp_cache_get( $cache_key, 'terms' );
-		if ( false !== $cache ) {
-			if ( 'all' === $_fields ) {
-				$cache = array_map( 'get_term', $cache );
-			}
 
-			$this->terms = $cache;
-			return $this->terms;
-		}
+		if ( 'count' === $_fields ) {
+			if ( false === $cache ) {
+				$cache = $wpdb->get_var( $this->request );
+				wp_cache_set( $cache_key, $cache, 'terms' );
+			}
 
-		if ( 'count' == $_fields ) {
-			$count = $wpdb->get_var( $this->request );
-			wp_cache_set( $cache_key, $count, 'terms' );
-			return $count;
+			return $cache;
 		}
 
-		$terms = $wpdb->get_results( $this->request );
-		if ( 'all' == $_fields || 'all_with_object_id' === $_fields ) {
-			update_term_cache( $terms );
+		if ( false === $cache ) {
+			$cache = $wpdb->get_results( $this->request );
+			wp_cache_set( $cache_key, $cache, 'terms' );
 		}
 
-		// Prime termmeta cache.
-		if ( $args['update_term_meta_cache'] ) {
-			$term_ids = wp_list_pluck( $terms, 'term_id' );
-			update_termmeta_cache( $term_ids );
-		}
+		$term_ids = wp_list_pluck( $cache, 'term_id' );
 
-		if ( empty( $terms ) ) {
+		if ( empty( $term_ids ) ) {
 			wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS );
 			return array();
 		}
 
+		// 'ids' requests only need full term objects in certain cases.
+		if ( 'ids' === $_fields && ! $child_of && ( ! $hierarchical || ! $args['hide_empty'] ) ) {
+			$terms = $cache;
+			if ( $args['update_term_meta_cache'] ) {
+				update_termmeta_cache( $term_ids );
+			}
+		} else {
+			_prime_term_caches( $term_ids, $args['update_term_meta_cache'] );
+			$terms = array_map( 'get_term', $term_ids );
+
+			if ( in_array( 'tr.object_id', $selects ) ) {
+				foreach ( $cache as $index => $result ) {
+					$terms[ $index ]->object_id = (int) $result->object_id;
+				}
+			}
+		}
+
 		if ( $child_of ) {
 			foreach ( $taxonomies as $_tax ) {
 				$children = _get_term_hierarchy( $_tax );
@@ -808,13 +807,8 @@ class WP_Term_Query {
 			}
 		}
 
-		wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );
-
-		if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
-			$terms = array_map( 'get_term', $terms );
-		}
-
 		$this->terms = $terms;
+
 		return $this->terms;
 	}
 
diff --git src/wp-includes/class-wp-term.php src/wp-includes/class-wp-term.php
index 8eb87efbe0..63381b6db0 100644
--- src/wp-includes/class-wp-term.php
+++ src/wp-includes/class-wp-term.php
@@ -140,6 +140,8 @@ final class WP_Term {
 				return false;
 			}
 
+			$_term = false;
+
 			// If a taxonomy was specified, find a match.
 			if ( $taxonomy ) {
 				foreach ( $terms as $match ) {
diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index f703b5a56b..c710125a6e 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -3851,7 +3851,7 @@ function wp_get_split_term( $old_term_id, $taxonomy ) {
  *
  * @param int $term_id Term ID.
  * @return bool Returns false if a term is not shared between multiple taxonomies or
- *              if splittng shared taxonomy terms is finished. 
+ *              if splittng shared taxonomy terms is finished.
  */
 function wp_term_is_shared( $term_id ) {
 	global $wpdb;
diff --git tests/phpunit/tests/term/cache.php tests/phpunit/tests/term/cache.php
index fb7a5a84ab..b303bc840a 100644
--- tests/phpunit/tests/term/cache.php
+++ tests/phpunit/tests/term/cache.php
@@ -229,14 +229,12 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		$term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 
 		$term = get_term_by( 'slug', 'burrito', 'post_tag' );
-		$num_queries++;
 		$this->assertEquals( 'Taco', $term->name );
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
 		// This should now hit cache.
+		$num_queries = $wpdb->num_queries;
 		$term = get_term_by( 'slug', 'burrito', 'post_tag' );
 		$this->assertEquals( 'Taco', $term->name );
 		$this->assertEquals( $num_queries, $wpdb->num_queries );
@@ -254,14 +252,12 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		$term_id = $this->factory->term->create( array( 'slug' => 'burrito', 'name' => 'Taco', 'taxonomy' => 'post_tag' ) );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 
 		$term = get_term_by( 'slug', 'burrito', 'post_tag' );
-		$num_queries++;
 		$this->assertEquals( 'Taco', $term->name );
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
 		// This should now hit cache.
+		$num_queries = $wpdb->num_queries;
 		$term = get_term_by( 'slug', 'burrito', 'post_tag' );
 		$this->assertEquals( 'Taco', $term->name );
 		$this->assertEquals( $num_queries, $wpdb->num_queries );
@@ -272,9 +268,8 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 
 		// This should not hit cache.
 		$term = get_term_by( 'slug', 'burrito', 'post_tag' );
-		$num_queries++;
 		$this->assertEquals( 'No Taco', $term->name );
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
+		$this->assertGreaterThan( $num_queries, $wpdb->num_queries );
 	}
 
 	/**
@@ -286,13 +281,12 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		$term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 
-		get_term_by( 'name', 'Burrito', 'post_tag' );
-		$num_queries++;
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
+		$term = get_term_by( 'name', 'Burrito', 'post_tag' );
+		$this->assertSame( 'Burrito', $term->name );
 
 		// This should now hit cache.
+		$num_queries = $wpdb->num_queries;
 		$term = get_term_by( 'name', 'Burrito', 'post_tag' );
 		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
@@ -309,13 +303,11 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		$term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'slug' => 'noburrito', 'taxonomy' => 'post_tag' ) );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 
 		get_term_by( 'name', 'Burrito', 'post_tag' );
-		$num_queries++;
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
 		// This should now hit cache.
+		$num_queries = $wpdb->num_queries;
 		get_term_by( 'name', 'Burrito', 'post_tag' );
 		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
@@ -325,8 +317,7 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 
 		// This should not hit cache.
 		get_term_by( 'name', 'burrito', 'post_tag' );
-		$num_queries++;
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
+		$this->assertGreaterThan( $num_queries, $wpdb->num_queries );
 	}
 
 	/**
@@ -338,13 +329,12 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		$term_id = $this->factory->term->create( array( 'name' => 'Burrito', 'taxonomy' => 'post_tag' ) );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 		$last_changed = wp_cache_get( 'last_changed', 'terms' );
 
 		$term1 = get_term_by( 'name', 'Burrito', 'post_tag' );
-		$num_queries++;
 
 		// Verify the term is cached.
+		$num_queries = $wpdb->num_queries;
 		$term2 = get_term_by( 'name', 'Burrito', 'post_tag' );
 		$this->assertEquals( $num_queries, $wpdb->num_queries );
 		$this->assertEquals( $term1, $term2 );
@@ -377,14 +367,12 @@ class Tests_Term_Cache extends WP_UnitTestCase {
 		add_term_meta( $term_id, 'foo', 'bar' );
 
 		clean_term_cache( $term_id, 'post_tag' );
-		$num_queries = $wpdb->num_queries;
 
 		$term = get_term_by( 'name', 'Burrito', 'post_tag' );
-		$num_queries++;
 		$this->assertTrue( $term instanceof WP_Term );
 		$this->assertSame( $term_id, $term->term_id );
-		$this->assertEquals( $num_queries, $wpdb->num_queries );
 
+		$num_queries = $wpdb->num_queries;
 		$term_meta = get_term_meta( $term_id, 'foo', true );
 		$num_queries++;
 		$this->assertSame( $term_meta, 'bar' );
diff --git tests/phpunit/tests/term/getTermBy.php tests/phpunit/tests/term/getTermBy.php
index 4adda74f5a..ea8c386779 100644
--- tests/phpunit/tests/term/getTermBy.php
+++ tests/phpunit/tests/term/getTermBy.php
@@ -108,15 +108,13 @@ class Tests_Term_GetTermBy extends WP_UnitTestCase {
 
 		clean_term_cache( $t, 'wptests_tax' );
 
-		$num_queries = $wpdb->num_queries;
 		$found = get_term_by( 'slug', 'foo', 'wptests_tax' );
-		$num_queries++;
 
 		$this->assertTrue( $found instanceof WP_Term );
 		$this->assertSame( $t, $found->term_id );
-		$this->assertSame( $num_queries, $wpdb->num_queries );
 
 		// Calls to `get_term()` should now hit cache.
+		$num_queries = $wpdb->num_queries;
 		$found2 = get_term( $t );
 		$this->assertSame( $t, $found->term_id );
 		$this->assertSame( $num_queries, $wpdb->num_queries );
@@ -172,30 +170,6 @@ class Tests_Term_GetTermBy extends WP_UnitTestCase {
 	/**
 	 * @ticket 21760
 	 */
-	public function test_query_should_not_contain_order_by_clause() {
-		global $wpdb;
-
-		$term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
-		$found = get_term_by( 'name', 'burrito', 'post_tag' );
-		$this->assertSame( $term_id, $found->term_id );
-		$this->assertNotContains( 'ORDER BY', $wpdb->last_query );
-	}
-
-	/**
-	 * @ticket 21760
-	 */
-	public function test_query_should_contain_limit_clause() {
-		global $wpdb;
-
-		$term_id = $this->factory->term->create( array( 'name' => 'burrito', 'taxonomy' => 'post_tag' ) );
-		$found = get_term_by( 'name', 'burrito', 'post_tag' );
-		$this->assertSame( $term_id, $found->term_id );
-		$this->assertContains( 'LIMIT 1', $wpdb->last_query );
-	}
-
-	/**
-	 * @ticket 21760
-	 */
 	public function test_prevent_recursion_by_get_terms_filter() {
 		$action = new MockAction();
 
diff --git tests/phpunit/tests/term/getTerms.php tests/phpunit/tests/term/getTerms.php
index 575e5ca1c0..01a79faddd 100644
--- tests/phpunit/tests/term/getTerms.php
+++ tests/phpunit/tests/term/getTerms.php
@@ -112,7 +112,7 @@ class Tests_Term_getTerms extends WP_UnitTestCase {
 		$this->assertEquals( 3, count( $terms ) );
 		$time1 = wp_cache_get( 'last_changed', 'terms' );
 		$this->assertNotEmpty( $time1 );
-		$this->assertEquals( $num_queries + 1, $wpdb->num_queries );
+		$this->assertEquals( $num_queries + 2, $wpdb->num_queries );
 
 		$num_queries = $wpdb->num_queries;
 
diff --git tests/phpunit/tests/term/isObjectInTerm.php tests/phpunit/tests/term/isObjectInTerm.php
index ed054f8ea3..5aa55d88a0 100644
--- tests/phpunit/tests/term/isObjectInTerm.php
+++ tests/phpunit/tests/term/isObjectInTerm.php
@@ -113,11 +113,9 @@ class Tests_IsObjectInTerm extends WP_UnitTestCase {
 		$o = 12345;
 		wp_set_object_terms( $o, $terms[0], 'wptests_tax' );
 
-		$num_queries = $wpdb->num_queries;
 		$this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[0] ) );
-		$num_queries++;
-		$this->assertSame( $num_queries, $wpdb->num_queries );
 
+		$num_queries = $wpdb->num_queries;
 		$this->assertFalse( is_object_in_term( $o, 'wptests_tax', $terms[1] ) );
 		$this->assertSame( $num_queries, $wpdb->num_queries );
 	}
@@ -134,17 +132,11 @@ class Tests_IsObjectInTerm extends WP_UnitTestCase {
 		$o = 12345;
 		wp_set_object_terms( $o, $terms[0], 'wptests_tax' );
 
-		$num_queries = $wpdb->num_queries;
 		$this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[0] ) );
-		$num_queries++;
-		$this->assertSame( $num_queries, $wpdb->num_queries );
 
 		wp_set_object_terms( $o, $terms[1], 'wptests_tax' );
 
-		$num_queries = $wpdb->num_queries;
 		$this->assertTrue( is_object_in_term( $o, 'wptests_tax', $terms[1] ) );
-		$num_queries++;
-		$this->assertSame( $num_queries, $wpdb->num_queries );
 	}
 
 	/**
diff --git tests/phpunit/tests/term/query.php tests/phpunit/tests/term/query.php
index b2e2a27621..a5e037aef4 100644
--- tests/phpunit/tests/term/query.php
+++ tests/phpunit/tests/term/query.php
@@ -324,6 +324,42 @@ class Tests_Term_Query extends WP_UnitTestCase {
 	}
 
 	/**
+	 * @ticket 37189
+	 * @group cache
+	 */
+	public function test_object_ids_should_be_fetched_from_cache() {
+		global $wpdb;
+
+		register_taxonomy( 'wptests_tax_1', 'post' );
+
+		$p = self::factory()->post->create();
+		$terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax_1' ) );
+
+		wp_set_object_terms( $p, array( $terms[0] ), 'wptests_tax_1' );
+
+		$query = new WP_Term_Query( array(
+			'taxonomy' => 'wptests_tax_1',
+			'object_ids' => $p,
+			'fields' => 'all_with_object_id',
+		) );
+		$found = $query->get_terms();
+		$found_ids = wp_list_pluck( $found, 'term_id' );
+		$this->assertEqualSets( array( $terms[0] ), $found_ids );
+
+		$num_queries = $wpdb->num_queries;
+
+		$query = new WP_Term_Query( array(
+			'taxonomy' => 'wptests_tax_1',
+			'object_ids' => $p,
+			'fields' => 'all_with_object_id',
+		) );
+		$found = $query->get_terms();
+		$found_ids = wp_list_pluck( $found, 'term_id' );
+		$this->assertEqualSets( array( $terms[0] ), $found_ids );
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+	}
+
+	/**
 	 * @ticket 38295
 	 * @group cache
 	 */
