Skip to content

Commit 13152bf

Browse files
Merge pull request #1099 from cloudinary/fix/long-query
Optimizing the query_relations long query
2 parents 562fb14 + 3061cff commit 13152bf

File tree

1 file changed

+44
-30
lines changed

1 file changed

+44
-30
lines changed

php/class-utils.php

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,19 +1009,16 @@ public static function attachment_url_to_postid( $url ) {
10091009
* @return array
10101010
*/
10111011
public static function query_relations( $public_ids, $urls = array() ) {
1012-
global $wpdb;
1013-
1014-
$wheres = array();
1015-
$searched_things = array();
1012+
$chunk_size = 25;
1013+
$results = array();
1014+
$tablename = self::get_relationship_table();
10161015

10171016
/**
10181017
* Filter the media context query.
10191018
*
10201019
* @hook cloudinary_media_context_query
10211020
* @since 3.2.0
1022-
*
10231021
* @param $media_context_query {string} The default media context query.
1024-
*
10251022
* @return {string}
10261023
*/
10271024
$media_context_query = apply_filters( 'cloudinary_media_context_query', 'media_context = %s' );
@@ -1031,43 +1028,60 @@ public static function query_relations( $public_ids, $urls = array() ) {
10311028
*
10321029
* @hook cloudinary_media_context_things
10331030
* @since 3.2.0
1034-
*
10351031
* @param $media_context_things {array} The default media context things.
1036-
*
10371032
* @return {array}
10381033
*/
10391034
$media_context_things = apply_filters( 'cloudinary_media_context_things', array( 'default' ) );
10401035

1036+
// Query for urls in chunks.
10411037
if ( ! empty( $urls ) ) {
1042-
// Do the URLS.
1043-
$list = implode( ', ', array_fill( 0, count( $urls ), '%s' ) );
1044-
$where = "(url_hash IN( {$list} ) AND {$media_context_query} )";
1045-
$searched_things = array_merge( $searched_things, array_map( 'md5', $urls ), $media_context_things );
1046-
$wheres[] = $where;
1038+
$results = array_merge( $results, self::run_chunked_query( 'url_hash', $urls, $chunk_size, $tablename, $media_context_query, $media_context_things ) );
10471039
}
1040+
// Query for public_ids in chunks.
10481041
if ( ! empty( $public_ids ) ) {
1049-
// Do the public_ids.
1050-
$list = implode( ', ', array_fill( 0, count( $public_ids ), '%s' ) );
1051-
$where = "(public_hash IN( {$list} ) AND {$media_context_query} )";
1052-
$searched_things = array_merge( $searched_things, array_map( 'md5', $public_ids ), $media_context_things );
1053-
$wheres[] = $where;
1042+
$results = array_merge( $results, self::run_chunked_query( 'public_hash', $public_ids, $chunk_size, $tablename, $media_context_query, $media_context_things ) );
10541043
}
10551044

1056-
$results = array();
1057-
1058-
if ( ! empty( array_filter( $wheres ) ) ) {
1059-
$tablename = self::get_relationship_table();
1060-
$sql = "SELECT * from {$tablename} WHERE " . implode( ' OR ', $wheres );
1061-
$prepared = $wpdb->prepare( $sql, $searched_things ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1062-
$cache_key = md5( $prepared );
1063-
$results = wp_cache_get( $cache_key, 'cld_delivery' );
1064-
if ( empty( $results ) ) {
1065-
$results = $wpdb->get_results( $prepared, ARRAY_A );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
1066-
wp_cache_add( $cache_key, $results, 'cld_delivery' );
1045+
return $results;
1046+
}
1047+
/**
1048+
* Run a chunked query and merge results.
1049+
*
1050+
* @param string $field The DB field to query (url_hash or public_hash).
1051+
* @param array $items The items to query.
1052+
* @param int $chunk_size Number of items per chunk.
1053+
* @param string $tablename The table name.
1054+
* @param string $media_context_query The media context SQL.
1055+
* @param array $media_context_things The media context values.
1056+
* @return array
1057+
*/
1058+
protected static function run_chunked_query( $field, $items, $chunk_size, $tablename, $media_context_query, $media_context_things ) {
1059+
global $wpdb;
1060+
1061+
$all_results = array();
1062+
$chunks = array_chunk( $items, $chunk_size );
1063+
1064+
foreach ( $chunks as $chunk ) {
1065+
$list = implode( ', ', array_fill( 0, count( $chunk ), '%s' ) );
1066+
$where = "({$field} IN( {$list} ) AND {$media_context_query} )";
1067+
$searched_things = array_merge( array_map( 'md5', $chunk ), $media_context_things );
1068+
$sql = "SELECT * from {$tablename} WHERE {$where}";
1069+
$prepared = $wpdb->prepare( $sql, $searched_things ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1070+
$cache_key = md5( $prepared );
1071+
$chunk_results = wp_cache_get( $cache_key, 'cld_delivery' );
1072+
1073+
if ( empty( $chunk_results ) ) {
1074+
$chunk_results = $wpdb->get_results( $prepared, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
1075+
1076+
wp_cache_add( $cache_key, $chunk_results, 'cld_delivery' );
1077+
}
1078+
1079+
if ( ! empty( $chunk_results ) ) {
1080+
$all_results = array_merge( $all_results, $chunk_results );
10671081
}
10681082
}
10691083

1070-
return $results;
1084+
return $all_results;
10711085
}
10721086

10731087
/**

0 commit comments

Comments
 (0)