itsource

mySQL 쿼리가 서버를 손상시키는 것 같습니다.

mycopycode 2023. 10. 19. 22:18
반응형

mySQL 쿼리가 서버를 손상시키는 것 같습니다.

워드프레스에서 상당히 복잡한 검색을 처리할 수 있는 mySQL 쿼리를 가지고 있습니다. 왜냐하면 저는 그 검색을 하는 데 어려움을 겪었기 때문입니다.wp_query내가 필요한 모든 것을 할 수 있도록 말입니다.

그러나 쿼리를 실행하는 데 시간이 오래 걸리는 경우도 있고(때로는 10초 이상!) 서버가 다운되는 것처럼 보이는 경우도 있습니다(미디어 템플 그리드).internal server error혹은Error establishing database connection.

쿼리에 일반적인 구문 오류가 있어서 충돌이 발생하는지는 확실하지 않지만 쿼리를 생성하는 PHP는 기본적으로 다음과 같습니다.

<?php

// declare wordpress database global
global $wpdb;

// order by option
$order = $_SESSION['search']['sort-by'];

// users lat, long and distance preferences
$lat = $_SESSION['search']['lat'];
$long = $_SESSION['search']['long'];
$radius = $_SESSION['search']['distance'];

// user search start/end date
$startDate = date('Ymd', strtotime($_SESSION['search']['from']));
$endDate = date('Ymd', strtotime($_SESSION['search']['to']));

// get the main category search ID
$maincat = get_term_by( 'slug', $_SESSION['search']['cat'], 'main-cat');
$maincat = $maincat->term_taxonomy_id;

// grab keywords, replace special chars and spaces
$keywords = $_SESSION['search']['keyword'];
$keywords = preg_replace('/[^A-Za-z0-9 ,]/u','', strip_tags($keywords));
$keywords = str_replace(' ', '', $keywords);

// put keywords into array
$subcatItems = explode(',', $keywords);
$keywords = $subcatItems;

// for each keywords get the sub category id's
$subcats = array();
$count = count($subcatItems) - 2;
for ($i = 0; $i <= $count; $i++) {
    $subcatItems[$i] = get_term_by( 'slug', $subcatItems[$i], 'sub-cat');
    if ($subcatItems[$i] != '') : 
        $subcatItems[$i] = $subcatItems[$i]->term_taxonomy_id;
        array_push($subcats, $subcatItems[$i]);
    endif;
}
if( $subcats != '' ) :
    $subcats = implode(',', $subcats);
endif;



// select
$query = 'SELECT SQL_CALC_FOUND_ROWS wp_posts.*, ';


// geo locate
$query .= '( 3959 * acos(
     cos( radians('.$lat.') ) 
     * cos( radians( lat ) ) 
     * cos( radians( lng ) - radians('.$long.') ) 
     + sin( radians('.$lat.') ) 
     * sin( radians( lat ) ) 
     ) ) 
 AS distance , lat AS  latitude , lng AS longitude ';


 // from
 $query .= 'FROM wp_posts ';


 // inner joins
 $query .= 'INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) ';
 if ( $keywords != '' ) :
    $query .= 'INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) ';
 endif;
 $query .= 'INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) ';
 $query .= 'INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) ';

 // if ordered by price, join post meta again
 if( $order == 'mt2.meta_value+0' ) :
     $query .= 'INNER JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id) ';
 endif;

 // if there are keywords 
 if ( $keywords != '' ) :
    $query .= 'INNER JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id) ';
 endif;

 // join table to geo locate
 $query .= 'INNER JOIN lat_lng_post ON wp_posts.ID = lat_lng_post.post_id ';


 // basic filter
 $query .= 'WHERE 1=1 ';
 $query .= 'AND wp_posts.post_type = "event" '; 
 $query .= 'AND wp_posts.post_status = "publish" ';


 // geo filter
 $query .= 'AND lat_lng_post.lat = lat ';
 $query .= 'AND lat_lng_post.lng = lng ';


 // date filter
 $query .= 'AND ( '; 
 $query .= '(wp_postmeta.meta_key LIKE "date_%_start-date" AND CAST(wp_postmeta.meta_value AS SIGNED) <= "'.$endDate.'") ';
 $query .= 'AND (mt1.meta_key LIKE "date_%_end-date" AND CAST(mt1.meta_value AS SIGNED) >= "'.$startDate.'") ';
 $query .= 'AND substr(wp_postmeta.meta_key, 1, 6) = substr(mt1.meta_key, 1, 6)  ';
 $query .= ') ';


 // taxonomies filter
 $query .= 'AND ( wp_term_relationships.term_taxonomy_id IN ('.$maincat.') ) ';

 // if keywords
 if ( $_SESSION['search']['keyword'] != '' ) :
    $query .= 'AND ( ';

    // for each keyword, and a statement to check post title
    $keywordCount = 0;
    foreach ( $keywords as $keyword ) :
        if( $keyword != '' ) :
            if( $keywordCount == 0 ) :
                $query .= '(wp_posts.post_title LIKE "%'.$keyword.'%") ';
            else :
                $query .= 'OR (wp_posts.post_title LIKE "%'.$keyword.'%") ';
            endif;
        endif;
        $keywordCount++;
    endforeach;

    // for each keyword, and a statement to check description
    foreach ( $keywords as $keyword ) :
        if( $keyword != '' ) :
            $query .= 'OR (mt3.meta_key = "description" AND mt3.meta_value LIKE "%'.$keyword.'%") ';
        endif;
    endforeach;

    // for each keyword, and a statement to check sub category taxonomy
    if( $subcats != '' ) :
        $query .= 'OR ( tt1.term_taxonomy_id IN ('.$subcats.') )';
    endif;

    $query .= ') ';
 endif;     


 // if ordered by adult
 if( $order == 'mt2.meta_value+0' ) :
     $query .= 'AND mt2.meta_key = "adult" ';
 endif;

 // grouping and sorting
 $query .= 'GROUP BY wp_posts.ID ';
 $query .= 'HAVING distance <= '.$radius.' ';
 $query .= 'ORDER BY '.$order.' ASC ';
 $query .= 'LIMIT 0, 10';

 $events = $wpdb->get_results( $query, 'OBJECT' ); 

?>

생각나는 사람 있으면 저한테 알려주세요!그리고 더 필요한 정보가 있다면 기꺼이 제공해 드립니다 :)

편집

검색에 키워드가 있을 때 쿼리가 훨씬 더 어려움을 겪는 것 같습니다.논리를 더 잘 쓸 수 있는 방법이 있을지 모르겠습니다.

if ( $_SESSION['search']['keyword'] != '' ) :
    $query .= 'AND ( ';

    // for each keyword, and a statement to check post title
    $keywordCount = 0;
    foreach ( $keywords as $keyword ) :
        if( $keyword != '' ) :
            if( $keywordCount == 0 ) :
                $query .= '(wp_posts.post_title LIKE "%'.$keyword.'%") ';
            else :
                $query .= 'OR (wp_posts.post_title LIKE "%'.$keyword.'%") ';
            endif;
        endif;
        $keywordCount++;
    endforeach;

    // for each keyword, and a statement to check description
    foreach ( $keywords as $keyword ) :
        if( $keyword != '' ) :
            $query .= 'OR (mt3.meta_key = "description" AND mt3.meta_value LIKE "%'.$keyword.'%") ';
        endif;
    endforeach;

    // for each keyword, and a statement to check sub category taxonomy
    if( $subcats != '' ) :
        $query .= 'OR ( tt1.term_taxonomy_id IN ('.$subcats.') )';
    endif;

    $query .= ') ';
 endif;

EDIT 2

방금 생각한 또 다른 생각인데, 쿼리를 별도의 쿼리로 나누는 것이 더 빠를까요?그러면 먼저 지오 쿼리를 완료하고 포스트 ID를 사용한 후 날짜 쿼리를 수행하면 키워드가 쿼리를 수행할 수 있습니까?SQL이 처음이라 최적화하는 방법을 잘 모르겠습니다. :/

조인(다중 조인 조건)에 최종 조건을 추가합니다.

큰 세트를 얻는 대신 조인에서 여러 조건을 사용한 후 마지막에 조건을 넣으면 세트가 작아지고 응답 시간이 더 단축될 수 있습니다.

예를 들어, 최종 조건이 있습니다.

AND wp_posts.post_type = "event"

첫 번째 조인에 넣을 수 있습니다.

INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) AND wp_posts.post_type = "event"
INNER JOIN...

등등.

언급URL : https://stackoverflow.com/questions/24569924/mysql-query-seems-to-crash-server

반응형