Index: wp-includes/default-filters.php
===================================================================
--- wp-includes/default-filters.php	(revision 21626)
+++ wp-includes/default-filters.php	(working copy)
@@ -192,6 +192,7 @@
 add_filter( 'editable_slug',            'urldecode'                           );
 add_filter( 'editable_slug',            'esc_textarea'                        );
 add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object'        );
+add_filter( 'wp_search_stopwords',      'wp_search_stopwords'                 );
 
 // Actions
 add_action( 'wp_head',             'wp_enqueue_scripts',              1     );
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 21626)
+++ wp-includes/functions.php	(working copy)
@@ -3637,3 +3637,26 @@
 	return true;
 }
 
+/**
+ * Common stopwords (terms) that are excluded from the separate term matching when searching for posts.
+ * The list of English stopwords is the approximate search engines list. MySQL has a much longer default list of full-text stopwords.
+ *
+ * @since 3.5.0
+ * @param array optional Terms to exclude when searching
+ *
+ * @return array
+ */
+function wp_search_stopwords( $in = array() ) {
+	$_words = explode( ',', _x('about,are,com,for,from,how,that,the,this,was,what,when,where,who,will,with,www', 'Comma separated list of common words to exclude when searching.') );
+	$words = array();
+
+	foreach( $_words as $word ) {
+		$word = trim($word, "\r\n\t ");
+		if ( !$word )
+			continue;
+		$words[] = $word;
+	}
+
+	return array_merge( $in, $words );
+}
+
Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php	(revision 21626)
+++ wp-includes/query.php	(working copy)
@@ -2174,7 +2174,9 @@
 		}
 
 		// If a search pattern is specified, load the posts that match
-		if ( !empty($q['s']) ) {
+		// Sanity check: search string shouldn't be more than 1600 characters
+		// (some browsers won't send more than 2000 characters incl. the URL in a urlencoded GET request).
+		if ( !empty($q['s']) && strlen($q['s']) < 1600 ) {
 			// 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() )
@@ -2183,11 +2185,25 @@
 				$q['search_terms'] = array($q['s']);
 			} else {
 				preg_match_all('/".*?("|$)|((?<=[\r\n\t ",+])|^)[^\r\n\t ",+]+/', $q['s'], $matches);
-				$q['search_terms'] = array_map('_search_terms_tidy', $matches[0]);
+				$q['_search_terms'] = array_map('_search_terms_tidy', $matches[0]);
+				$q['search_terms'] = array();
+				$stopwords = apply_filters_ref_array( 'wp_search_stopwords', array( array(), &$this ) );
+
+				foreach ( (array) $q['_search_terms'] as $term ) {
+					if ( empty($term) || strlen($term) < 3 || in_array( $term, $stopwords, true ) )
+						continue;
+					$q['search_terms'][] = $term;
+				}
+
+				unset($q['_search_terms']);
+				// if the search string has only short terms or stopwords, or is more than 10 terms long, match it as sentence
+				if ( empty($q['search_terms']) || count($q['search_terms']) > 10 )
+					$q['search_terms'] = array($q['s']);
 			}
+
 			$n = !empty($q['exact']) ? '' : '%';
 			$searchand = '';
-			foreach( (array) $q['search_terms'] as $term ) {
+			foreach( $q['search_terms'] as $term ) {
 				$term = esc_sql( like_escape( $term ) );
 				$search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
 				$searchand = ' AND ';
