Index: src/wp-includes/http.php
===================================================================
--- src/wp-includes/http.php	(revision 37318)
+++ src/wp-includes/http.php	(working copy)
@@ -598,6 +598,7 @@
  * Attached to the http_request_host_is_external filter.
  *
  * @since 3.6.0
+ * @since 4.6.0 Converted to use get_sites()
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  * @staticvar array $queried
@@ -615,7 +616,14 @@
 		return true;
 	if ( isset( $queried[ $host ] ) )
 		return $queried[ $host ];
-	$queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) );
+
+	$result = get_sites( array(
+		'domain' => $host,
+		'count'  => true
+	) );
+
+	$queried[ $host ] = (bool) $result;
+
 	return $queried[ $host ];
 }
 
Index: src/wp-includes/ms-blogs.php
===================================================================
--- src/wp-includes/ms-blogs.php	(revision 37318)
+++ src/wp-includes/ms-blogs.php	(working copy)
@@ -468,6 +468,67 @@
 }
 
 /**
+ *
+ * Retrieve list of sites matching criteria.
+ *
+ * The defaults are as follows:
+ *
+ * @since 4.6.0
+ *
+ * @see WP_Site_Query::parse_query()
+ *
+ * @param string|array $args {
+ *     Optional. Array or query string of site query parameters. Default empty.
+ *
+ *     @type array        $site__in         Array of site IDs to include. Default empty.
+ *     @type array        $site__not_in     Array of site IDs to exclude. Default empty.
+ *     @type bool         $count            Whether to return a site count (true) or array of site objects.
+ *                                          Default false.
+ *     @type array        $date_query       Date query clauses to limit sites by. See WP_Date_Query.
+ *                                          Default null.
+ *     @type string       $fields           Site fields to return. Accepts 'ids' for site IDs only or empty
+ *                                          for all fields. Default empty.
+ *     @type int          $ID               Currently unused.
+ *     @type int          $number           Maximum number of sites to retrieve. Default null (no limit).
+ *     @type int          $offset           Number of sites to offset the query. Used to build LIMIT clause.
+ *                                          Default 0.
+ *     @type bool         $no_found_rows    Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
+ *     @type string|array $orderby          Site status or array of statuses. To use 'meta_value' or
+ *                                          'meta_value_num', `$meta_key` must also be defined. To sort by a
+ *                                          specific `$meta_query` clause, use that clause's array key. Accepts
+ *                                          'site_agent', 'site_approved', 'site_author', 'site_author_email',
+ *                                          'site_author_IP', 'site_author_url', 'site_content', 'site_date',
+ *                                          'site_date_gmt', 'blog_id', 'site_karma', 'site_parent', 'site_id',
+ *                                          'site_type', 'user_id', 'site__in', 'meta_value', 'meta_value_num',
+ *                                          the value of $meta_key, and the array keys of `$meta_query`. Also
+ *                                          accepts false, an empty array, or 'none' to disable `ORDER BY` clause.
+ *                                          Default 'site_date_gmt'.
+ *     @type string       $order            How to order retrieved sites. Accepts 'ASC', 'DESC'. Default 'DESC'.
+ *     @type string       $domain           Limit results to those affiliated with a given network ID.
+ *                                          Default current network ID.
+ *     @type array        $domain__in       Array of domains to include affiliated sites for. Default empty.
+ *     @type array        $domain__not_in   Array of domains to exclude affiliated sites for. Default empty.
+ *     @type string       $path             Limit results to those affiliated with a given network ID.
+ *                                          Default current network ID.
+ *     @type array        $path__in         Array of paths to include affiliated sites for. Default empty.
+ *     @type array        $path__not_in     Array of paths to exclude affiliated sites for. Default empty.
+ *     @type int          $network_id       Limit results to those affiliated with a given network ID.
+ *                                          Default current network ID.
+ *     @type array        $network__in      Array of network IDs to include affiliated sites for. Default empty.
+ *     @type array        $network__not_in  Array of network IDs to exclude affiliated sites for. Default empty.
+ *     @type string       $search           Search term(s) to retrieve matching sites for. Default empty.
+ *     @type bool         $update_site_cache Whether to prime the cache for site networks. Default false.
+ * }
+ * @return array List of sites.
+ */
+function get_sites( $args = array() ) {
+	$query = new WP_Site_Query();
+
+	return $query->query( $args );
+}
+
+
+/**
  * Retrieve option value for a given blog id based on name of option.
  *
  * If the option does not exist or does not have a value, then the return value
Index: src/wp-includes/ms-functions.php
===================================================================
--- src/wp-includes/ms-functions.php	(revision 37318)
+++ src/wp-includes/ms-functions.php	(working copy)
@@ -308,18 +308,22 @@
 	global $wpdb;
 
 	$domain = strtolower( $domain );
-	$path = strtolower( $path );
-	$id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' );
+	$path   = strtolower( $path );
+	$id     = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' );
 
-	if ( $id == -1 ) // blog does not exist
+	if ( $id == - 1 ) // blog does not exist
+	{
 		return 0;
-	elseif ( $id )
+	} elseif ( $id ) {
 		return (int) $id;
+	}
 
-	$id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s and path = %s /* get_blog_id_from_url */", $domain, $path ) );
+	$args   = array( 'domain' => $domain, 'path' => $path, 'fields' => 'ids' );
+	$result = get_sites( $args );
+	$id     = array_shift( $result );
+	if ( ! $id ) {
+		wp_cache_set( md5( $domain . $path ), - 1, 'blog-id-cache' );
 
-	if ( ! $id ) {
-		wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' );
 		return 0;
 	}
 
@@ -1255,21 +1259,29 @@
  * @return int
  */
 function domain_exists($domain, $path, $site_id = 1) {
-	global $wpdb;
 	$path = trailingslashit( $path );
-	$result = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) );
 
+	$result = get_sites( array(
+		'path'    => $path,
+		'domain'  => $domain,
+		'network' => $site_id,
+		'number'  => 1,
+		'fields'  => 'ids'
+	) );
+
+	$site = array_shift( $result );
+
 	/**
 	 * Filter whether a blogname is taken.
 	 *
 	 * @since 3.5.0
 	 *
-	 * @param int|null $result  The blog_id if the blogname exists, null otherwise.
+	 * @param int|null $site  The blog_id if the blogname exists, null otherwise.
 	 * @param string   $domain  Domain to be checked.
 	 * @param string   $path    Path to be checked.
 	 * @param int      $site_id Site ID. Relevant only on multi-network installs.
 	 */
-	return apply_filters( 'domain_exists', $result, $domain, $path, $site_id );
+	return apply_filters( 'domain_exists', $site, $domain, $path, $site_id );
 }
 
 /**
@@ -2246,6 +2258,7 @@
  * Update the network-wide site count.
  *
  * @since 3.7.0
+ * @since 4.6.0 Converted to use get_sites()
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  */
@@ -2252,7 +2265,14 @@
 function wp_update_network_site_counts() {
 	global $wpdb;
 
-	$count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $wpdb->siteid) );
+	$count = get_sites( array(
+		'network_id' => $wpdb->siteid,
+		'spam'       => 0,
+		'deleted'    => 0,
+		'archived'   => 0,
+		'count'      => true
+	) );
+
 	update_site_option( 'blog_count', $count );
 }
 
@@ -2408,6 +2428,7 @@
  * Return an array of sites for a network or networks.
  *
  * @since 3.7.0
+ * @since 4.6.0 Converted to use get_sites()
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
@@ -2432,9 +2453,6 @@
 function wp_get_sites( $args = array() ) {
 	global $wpdb;
 
-	if ( wp_is_large_network() )
-		return array();
-
 	$defaults = array(
 		'network_id' => $wpdb->siteid,
 		'public'     => null,
@@ -2448,38 +2466,18 @@
 
 	$args = wp_parse_args( $args, $defaults );
 
-	$query = "SELECT * FROM $wpdb->blogs WHERE 1=1 ";
+	// Make sure count is disabled.
+	$args['count'] = false;
 
-	if ( isset( $args['network_id'] ) && ( is_array( $args['network_id'] ) || is_numeric( $args['network_id'] ) ) ) {
-		$network_ids = implode( ',', wp_parse_id_list( $args['network_id'] ) );
-		$query .= "AND site_id IN ($network_ids) ";
-	}
+	$_sites  = get_sites( $args );
 
-	if ( isset( $args['public'] ) )
-		$query .= $wpdb->prepare( "AND public = %d ", $args['public'] );
+	$results = array();
 
-	if ( isset( $args['archived'] ) )
-		$query .= $wpdb->prepare( "AND archived = %d ", $args['archived'] );
-
-	if ( isset( $args['mature'] ) )
-		$query .= $wpdb->prepare( "AND mature = %d ", $args['mature'] );
-
-	if ( isset( $args['spam'] ) )
-		$query .= $wpdb->prepare( "AND spam = %d ", $args['spam'] );
-
-	if ( isset( $args['deleted'] ) )
-		$query .= $wpdb->prepare( "AND deleted = %d ", $args['deleted'] );
-
-	if ( isset( $args['limit'] ) && $args['limit'] ) {
-		if ( isset( $args['offset'] ) && $args['offset'] )
-			$query .= $wpdb->prepare( "LIMIT %d , %d ", $args['offset'], $args['limit'] );
-		else
-			$query .= $wpdb->prepare( "LIMIT %d ", $args['limit'] );
+	foreach ( $_sites as $_site ) {
+		$results[] = get_site( $_site, ARRAY_A );
 	}
 
-	$site_results = $wpdb->get_results( $query, ARRAY_A );
-
-	return $site_results;
+	return $results;
 }
 
 /**
Index: src/wp-includes/ms-load.php
===================================================================
--- src/wp-includes/ms-load.php	(revision 37318)
+++ src/wp-includes/ms-load.php	(working copy)
@@ -154,6 +154,7 @@
  * Retrieve a site object by its domain and path.
  *
  * @since 3.9.0
+ * @since 4.6.0 Converted to use get_sites()
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
@@ -231,27 +232,28 @@
 	$domains = array( $domain );
 	if ( 'www.' === substr( $domain, 0, 4 ) ) {
 		$domains[] = substr( $domain, 4 );
-		$search_domains = "'" . implode( "', '", $wpdb->_escape( $domains ) ) . "'";
 	}
 
-	if ( count( $paths ) > 1 ) {
-		$search_paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'";
-	}
+	$args = array(
+		'path__in'   => $path,
+		'domain__in' => $domains,
+		'number'     => 1
+	);
 
 	if ( count( $domains ) > 1 && count( $paths ) > 1 ) {
-		$site = $wpdb->get_row( "SELECT * FROM $wpdb->blogs WHERE domain IN ($search_domains) AND path IN ($search_paths) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1" );
+		$args['orderby'] = 'domain_length path_length';
+		$args['order']   = 'DESC DESC';
 	} elseif ( count( $domains ) > 1 ) {
-		$sql = $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE path = %s", $paths[0] );
-		$sql .= " AND domain IN ($search_domains) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1";
-		$site = $wpdb->get_row( $sql );
+		$args['orderby'] = 'domain_length';
+		$args['order']   = 'DESC';
 	} elseif ( count( $paths ) > 1 ) {
-		$sql = $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s", $domains[0] );
-		$sql .= " AND path IN ($search_paths) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
-		$site = $wpdb->get_row( $sql );
-	} else {
-		$site = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->blogs WHERE domain = %s AND path = %s", $domains[0], $paths[0] ) );
+		$args['orderby'] = 'path_length';
+		$args['order']   = 'DESC';
 	}
 
+	$result = get_sites( $args );
+
+	$site   = array_shift( $result );
 	if ( $site ) {
 		// @todo get_blog_details()
 		return $site;
