diff --git src/wp-includes/class-wp-query.php src/wp-includes/class-wp-query.php
index f8ead26..5964685 100644
--- src/wp-includes/class-wp-query.php
+++ src/wp-includes/class-wp-query.php
@@ -581,6 +581,7 @@ class WP_Query {
 			'post_parent__not_in',
 			'author__in',
 			'author__not_in',
+			'search_columns',
 		);
 
 		foreach ( $array_keys as $key ) {
@@ -605,6 +606,7 @@ class WP_Query {
 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
 	 * @since 5.0.0 Introduced the `$meta_compare_key` parameter.
+	 * @since 5.0.0 Introduced the `$search_columns` parameter.
 	 *
 	 * @param string|array $query {
 	 *     Optional. Array or string of Query parameters.
@@ -697,6 +699,8 @@ class WP_Query {
 	 *                                                 the 'wp_query_search_exclusion_prefix' filter.
 	 *     @type int          $second                  Second of the minute. Default empty. Accepts numbers 0-60.
 	 *     @type bool         $sentence                Whether to search by phrase. Default false.
+ 	 *     @type array        $search_columns          Array of column names to be searched. Accepts 'post_title',
+	 *                                                 'post_excerpt' and 'post_content'. Default empty array.
 	 *     @type bool         $suppress_filters        Whether to suppress filters. Default false.
 	 *     @type string       $tag                     Tag slug. Comma-separated (either), Plus-separated (all).
 	 *     @type array        $tag__and                An array of tag ids (AND in).
@@ -1300,7 +1304,7 @@ class WP_Query {
 		global $wpdb;
 
 		$search = '';
-
+		
 		// added slashes screw with quote grouping when done early, so done later
 		$q['s'] = stripslashes( $q['s'] );
 		if ( empty( $_GET['s'] ) && $this->is_main_query() ) {
@@ -1328,6 +1332,35 @@ class WP_Query {
 		$searchand                 = '';
 		$q['search_orderby_title'] = array();
 
+		$search_columns           = $q['search_columns'];
+		$default_search_columns   = array( 'post_title', 'post_excerpt', 'post_content' );
+		$supported_search_columns = $default_search_columns;
+
+		if ( ! $search_columns ) {
+			$search_columns = $default_search_columns;
+		}
+
+		/**
+		* Filters the columns to search in a WP_Query search.
+		*
+		* The supported columns are `post_title`, `post_excerpt` and `post_content`.
+		* They are all included by default.
+		*
+		* @since 5.0.0
+		*
+		* @param string[] $search_columns Array of column names to be searched.
+		* @param string   $search         Text being searched.
+		* @param WP_Query $this           The current WP_Query instance.
+		*/
+		$search_columns = (array) apply_filters( 'post_search_columns', $search_columns, $q['s'], $this );
+
+		// Use only supported search columns.
+		$search_columns = array_intersect( $search_columns, $supported_search_columns );
+
+		if ( ! $search_columns ) {
+			$search_columns = $default_search_columns;
+		}
+
 		/**
 		 * Filters the prefix that indicates that a search term should be excluded from results.
 		 *
@@ -1355,8 +1388,17 @@ class WP_Query {
 				$q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
 			}
 
-			$like      = $n . $wpdb->esc_like( $term ) . $n;
-			$search   .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
+			$like = $n . $wpdb->esc_like( $term ) . $n;
+
+			$searches = array();
+			foreach ( (array) $search_columns as $search_column ) {
+				$searches[] = $wpdb->prepare( "({$wpdb->posts}.{$search_column} $like_op %s)", $like );
+			}
+
+			if ( $searches ) {
+				$search .= "{$searchand}(" . join( " $andor_op", $searches ) . ')';
+			}
+
 			$searchand = ' AND ';
 		}
 
diff --git tests/phpunit/tests/query/searchColumns.php tests/phpunit/tests/query/searchColumns.php
new file mode 100644
index 0000000..1671619
--- /dev/null
+++ tests/phpunit/tests/query/searchColumns.php
@@ -0,0 +1,381 @@
+<?php
+/**
+ * Testing the search columns support in `WP_Query`.
+ *
+ * @package WordPress\UnitTests
+ * @since 5.0.0
+ */
+
+/**
+ * Test cases for the search columns feature.
+ *
+ * @group query
+ * @group search
+ *
+ * @since 5.0.0
+ */
+class Tests_Query_SearchColumns extends WP_UnitTestCase {
+	/**
+	 * The post ID of the first fixture post.
+	 *
+	 * @since 5.0.0
+	 * @var int $pid1
+	 */
+	protected static $pid1;
+
+	/**
+	 * The post ID of the second fixture post.
+	 *
+	 * @since 5.0.0
+	 * @var int $pid2
+	 */
+	protected static $pid2;
+
+	/**
+	 * The post ID of the third fixture post.
+	 *
+	 * @since 5.0.0
+	 * @var int $pid3
+	 */
+	protected static $pid3;
+
+	/**
+	 * Create posts fixtures.
+	 *
+	 * @param WP_UnitTest_Factory $factory The factory instance.
+	 */
+	public static function wpSetUpBeforeClass( $factory ) {
+		self::$pid1 = self::factory()->post->create(
+			array(
+				'post_status'  => 'publish',
+				'post_title'   => 'foo title',
+				'post_excerpt' => 'foo excerpt',
+				'post_content' => 'foo content',
+			)
+		);
+		self::$pid2 = self::factory()->post->create(
+			array(
+				'post_status'  => 'publish',
+				'post_title'   => 'bar title',
+				'post_excerpt' => 'foo bar excerpt',
+				'post_content' => 'foo bar content',
+			)
+		);
+
+		self::$pid3 = self::factory()->post->create(
+			array(
+				'post_status'  => 'publish',
+				'post_title'   => 'baz title',
+				'post_excerpt' => 'baz bar excerpt',
+				'post_content' => 'baz bar foo content',
+			)
+		);
+	}
+
+	/**
+	 * The search should use default search columns when search columns are empty.
+	 */
+	public function test_s_should_use_default_search_columns_when_empty_search_columns() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array(),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertContains( 'post_title', $q->request );
+		$this->assertContains( 'post_excerpt', $q->request );
+		$this->assertContains( 'post_content', $q->request );
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the post_title search column.
+	 */
+	public function test_s_should_support_post_title_search_column() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_title' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_excerpt` search column.
+	 */
+	public function test_s_should_support_post_excerpt_search_column() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_excerpt' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1, self::$pid2 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_content` search column.
+	 */
+	public function test_s_should_support_post_content_search_column() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_title` and `post_excerpt` search columns together.
+	 */
+	public function test_s_should_support_post_title_and_post_excerpt_search_columns() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_title', 'post_excerpt' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1, self::$pid2 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_title` and `post_content` search columns together.
+	 */
+	public function test_s_should_support_post_title_and_post_content_search_columns() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_title', 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_excerpt` and `post_content` search columns together.
+	 */
+	public function test_s_should_support_post_excerpt_and_post_content_search_columns() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_excerpt', 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support the `post_title`, `post_excerpt` and `post_content` search columns together.
+	 */
+	public function test_s_should_support_post_title_and_post_excerpt_and_post_content_search_columns() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_title', 'post_excerpt', 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should use default support columns when using a non existing search column.
+	 */
+	public function test_s_should_use_default_search_columns_when_using_non_existing_search_column() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_non_existing_column' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertContains( 'post_title', $q->request );
+		$this->assertContains( 'post_excerpt', $q->request );
+		$this->assertContains( 'post_content', $q->request );
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support ignore a non existing search column when used together with a supported one.
+	 */
+	public function test_s_should_ignore_non_existing_search_column_when_used_with_supported_one() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo',
+				'search_columns' => array( 'post_title', 'post_non_existing_column' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid1 ), $q->posts );
+	}
+
+	/**
+	 * The search should support search columns when searching multiple terms.
+	 */
+	public function test_s_should_support_search_columns_when_searching_multiple_terms() {
+		$q = new WP_Query(
+			array(
+				's'              => 'foo bar',
+				'search_columns' => array( 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support search columns when searching for a sentence.
+	 */
+	public function test_s_should_support_search_columns_when_sentence_true() {
+		$q = new WP_Query(
+			array(
+				's'              => 'bar foo',
+				'search_columns' => array( 'post_content' ),
+				'sentence'       => true,
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support search columns when searching for a sentence.
+	 */
+	public function test_s_should_support_search_columns_when_sentence_false() {
+		$q = new WP_Query(
+			array(
+				's'              => 'bar foo',
+				'search_columns' => array( 'post_content' ),
+				'sentence'       => false,
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * The search should support search columns when searched with a term exclusion.
+	 */
+	public function test_s_should_support_search_columns_when_searched_with_term_exclusion() {
+		$q = new WP_Query(
+			array(
+				's'              => 'bar -baz',
+				'search_columns' => array( 'post_excerpt', 'post_content' ),
+				'fields'         => 'ids',
+			)
+		);
+
+		$this->assertEqualSets( array( self::$pid2 ), $q->posts );
+	}
+
+	/**
+	 * The search columns should be filterable with the `post_search_columns` filter.
+	 */
+	public function test_search_columns_should_be_filterable() {
+		add_filter( 'post_search_columns', array( $this, 'post_supported_search_column' ), 10, 3 );
+		$q = new WP_Query(
+			array(
+				's'      => 'foo',
+				'fields' => 'ids',
+			)
+		);
+		remove_filter( 'post_search_columns', array( $this, 'post_supported_search_column' ) );
+
+		$this->assertEqualSets( array( self::$pid1 ), $q->posts );
+	}
+
+	/**
+	 * Filter callback that sets a supported search column.
+	 *
+	 * @param  string[] $search_columns Array of column names to be searched.
+	 * @param  string   $search         Text being searched.
+	 * @param  WP_Query $wp_query       The current WP_Query instance.
+	 * @return string[] $search_columns Array of column names to be searched.
+	 */
+	public function post_supported_search_column( $search_columns, $search, $wp_query ) {
+		$search_columns = array( 'post_title' );
+		return $search_columns;
+	}
+
+	/**
+	 * The search columns should not be filterable when using non supported search columns.
+	 */
+	public function test_search_columns_should_not_filterable_when_non_supported_search_columns() {
+		add_filter( 'post_search_columns', array( $this, 'post_non_supported_search_column' ), 10, 3 );
+		$q = new WP_Query(
+			array(
+				's'      => 'foo',
+				'fields' => 'ids',
+			)
+		);
+		remove_filter( 'post_search_columns', array( $this, 'post_non_supported_search_column' ) );
+
+		$this->assertNotContains( 'post_name', $q->request );
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * Filter callback that sets an existing but non supported search column.
+	 *
+	 * @param  string[] $search_columns Array of column names to be searched.
+	 * @param  string   $search         Text being searched.
+	 * @param  WP_Query $wp_query       The current WP_Query instance.
+	 * @return string[] $search_columns Array of column names to be searched.
+	 */
+	public function post_non_supported_search_column( $search_columns, $search, $wp_query ) {
+		$search_columns = array( 'post_name' );
+		return $search_columns;
+	}
+
+	/**
+	 * The search columns should not be filterable with non existing search columns.
+	 */
+	public function xtest_search_columns_should_not_filterable_non_existing_search_column() {
+		add_filter( 'post_search_columns', array( $this, 'post_non_existing_search_column' ), 10, 3 );
+		$q = new WP_Query(
+			array(
+				's'      => 'foo',
+				'fields' => 'ids',
+			)
+		);
+		remove_filter( 'post_search_columns', array( $this, 'post_non_existing_search_column' ) );
+
+		$this->assertNotContains( 'post_non_existing_column', $q->request );
+		$this->assertEqualSets( array( self::$pid1, self::$pid2, self::$pid3 ), $q->posts );
+	}
+
+	/**
+	 * Filter callback that sets a non existing search column.
+	 *
+	 * @param  string[] $search_columns Array of column names to be searched.
+	 * @param  string   $search         Text being searched.
+	 * @param  WP_Query $wp_query       The current WP_Query instance.
+	 * @return string[] $search_columns Array of column names to be searched.
+	 */
+	public function post_non_existing_search_column( $search_columns, $search, $wp_query ) {
+		$search_columns = array( 'post_non_existing_column' );
+		return $search_columns;
+	}
+
+}
