2013-12-06 4 views
0

Что делать, чтобы сделать мой код быстрее для поискового вызова.?
Я попытался положить его в временную таблицу. Проблема: создание временной таблицы заняло 4,56 секунды. Количество строк в wp_bp_xprofile_data составляет почти 25 тысяч. Я не знаю, почему для этого потребуется много времени.Оптимизировать sql-запрос для разбивки на страницы

Также, когда я знаю, когда соединение было закрыто. Это обновление каждой страницы?

// 
      //all variable are processed here.... 
      // 

    $sql = "SELECT 
      DN.User_ID, 
      case when (FN.user_id is null or (length(trim(FN.meta_value)) = 0)) 
       and (LN.user_id is null or (length(trim(LN.meta_value)) = 0)) then DN.value 
       else trim(concat(FN.meta_value, ' ', LN.meta_value)) end as Name, 
      DN.Value DisplayName, 
      COALESCE(G.Value, '') Gender, 
      COALESCE(BD.Value, '') Birthday, 
      COALESCE(FLOOR(DATEDIFF(CURRENT_DATE, STR_TO_DATE(BD.value,'%m/%d/%Y'))/365), '') Age, 
      COALESCE(P.Value, '') Phone, 
      COALESCE(E.Value, '') Email, 
      COALESCE(O.Value, '') Occupation, 
      COALESCE(R.Value, '') Region, 
      COALESCE(PR.Value, '') Province, 
      COALESCE(C.Value, '') City, 
      COALESCE(CC.Value, '') CurrentCountry 
    FROM wp_bp_xprofile_data DN 
      LEFT JOIN wp_bp_xprofile_data G 
       ON DN.User_ID = G.User_ID AND G.field_id = 270 
      LEFT JOIN wp_bp_xprofile_data BD 
       ON DN.User_ID = BD.User_ID AND BD.field_id = 274 
      LEFT JOIN wp_bp_xprofile_data P 
       ON DN.User_ID = P.User_ID AND P.field_id = 275 
      LEFT JOIN wp_bp_xprofile_data E 
       ON DN.User_ID = E.User_ID AND E.field_id = 286 
      LEFT JOIN wp_bp_xprofile_data O 
       ON DN.User_ID = O.User_ID AND O.field_id = 71 
      LEFT JOIN wp_bp_xprofile_data CC 
       ON DN.User_ID = CC.User_ID AND CC.field_id = 73 
      LEFT JOIN wp_bp_xprofile_data R 
       ON DN.User_ID = R.User_ID AND R.field_id = 24 
      LEFT JOIN wp_bp_xprofile_data PR 
       ON DN.User_ID = PR.User_ID AND PR.field_id = 355 
      LEFT JOIN wp_bp_xprofile_data C 
       ON DN.User_ID = C.User_ID AND C.field_id = 354 
      LEFT JOIN wp_usermeta FN 
       ON DN.User_ID = FN.User_ID AND FN.meta_key = 'first_name' 
      LEFT JOIN wp_usermeta LN 
       ON DN.User_ID = LN.User_ID AND LN.meta_key = 'last_name' 
    where DN.field_id = 1 "; 

    if(!empty($_region)) 
    { 
     $sql .= " AND R.User_ID IS NOT NULL AND R.Value = '".$_region."' "; 
    } 
    if(!empty($_province)) 
    { 
     $sql .= " AND PR.User_ID IS NOT NULL AND PR.Value LIKE '".$_province."%' "; 
    } 
    if(!empty($_city)) 
    { 
     $sql .= " AND C.user_id IS NOT NULL AND C.Value LIKE '".$_city."%' "; 
    } 
    if(!empty($_ageMin) && !empty($_ageMax)) 
    { 
     $sql .= " AND BD.User_ID IS NOT NULL AND FLOOR(DATEDIFF(CURRENT_DATE, STR_TO_DATE(BD.value,'%m/%d/%Y'))/365) BETWEEN ".$_ageMin." AND ".$_ageMax; 
    } 
    if(!empty($_occupation)) 
    { 
     $sql .= " AND O.User_ID IS NOT NULL AND O.Value = '".$_occupation."' "; 
    } 
    if(!empty($_gender)) 
    { 
     $sql .= " AND G.User_ID IS NOT NULL AND G.Value = '".$_gender."' "; 
    } 
    if(!empty($_country)) 
    { 
     $sql .= " AND CC.User_ID IS NOT NULL AND CC.Value = '".$_country."' "; 
    } 

    if(isset($search_val)){ 
     $sql .= " 
      AND 
      (FN.meta_value LIKE '%".$search_val."%' OR 
      LN.meta_value LIKE '%".$search_val."%' OR 
      E.Value LIKE '%".$search_val."%' OR 
      O.Value LIKE '%".$search_val."%' OR 
      R.Value LIKE '%".$search_val."%' OR 
      PR.Value LIKE '%".$search_val."%' OR 
      C.Value LIKE '%".$search_val."%' OR 
      CC.Value LIKE '%".$search_val."%') 
     "; 
    } 

    $maxRow = $wpdb->getResults($sql); 
    $limit = 30; 
    $maxPage = ceil($maxRow/$limit); 

    if(!empty($page)){ 
     $start = ($limit * $page) - $limit; 
    }else{ 
     $start = 0; 
    } 

    Generate_Pagination($maxRow); 

    $sql .= " LIMIT ".$start." , ".$limit; 

    $datas = $wpdb->getResults($sql); 

    foreach($data as $data){ 
     //output data; 
    } 
    ?> 

Использование Explain

enter image description here

При удалении этого кода

FN.meta_value LIKE '% "$ search_val." %' ИЛИ ​​
LN.meta_value LIKE ' % ". $ search_val."% 'or

Ускорит запрос. wp_usermeta имеет 300 тыс. Строк. также имеет различные meta_key

таблица wp_usermeta

 ` umeta_id | user_id | meta_key | meta_value` 
+0

можете ли вы объяснить причину этого запроса? –

ответ

0

Я заметил, что вы выдачи

$maxRow = $wpdb->getResults($sql); 

перед присоединением к LIMIT с OFFSET. Это приведет к получению еще многих записей, чем того, что вам нужно для разбивки на страницы.

Вы выдавшее

$datas = $wpdb->getResults($sql); 

после прикрепления LIMIT, который прекрасно.

Вы должны устранить первый звонок getResults, и ваше качество улучшится.

+0

, но целью этого является создание подкачки, например 'Prev | 2 | 3 | 4 | Next' – Cindy93

+0

Это делается с использованием ваших вторых 'getResults'. не первый. Я думаю, что целью первых «getResults» является просто подсчет строк. Если это так, то я чувствую, что есть лучшие способы получить количество строк. И используйте правильную терминологию. 'Paging' отличается от' Pagination'. То, что вы хотите, это «Pagination». – Litmus

+0

yes Цель первого - получить количество строк. – Cindy93

1

Попробуйте использовать SQL_CALC_FOUND_ROWS

$sql = 'SELECT SQL_CALC_FOUND_ROWS ... LIMIT ' . $limit; 

    $rows = $this->_db->fetchAll($sql);                  
    $data = array(                       
     "total" => $this->_db->fetchOne('SELECT FOUND_ROWS()'),    
     "rows" => $rows                      
    ); 
0

Ваш основной проблемой является поиск.

Вы используете «% ...%», который предотвращает использование простых индексов. Это означает, что для этого нужно проверить всю таблицу. Некоторые системы баз данных способны индексировать такие запросы (у Postgresql есть такая возможность), но вам нужна какая-то довольно продвинутая настройка, чтобы заставить их работать быстро.

http://www.postgresql.org/docs/8.3/static/textsearch-debugging.html

MySQL, вероятно, имеет что-то эквивалент.

Как сказано, в большинстве случаев вы можете уменьшить набор строк, поставив тесты, которые не используют «% ...» сначала в предложении WHERE. Это похоже на то, что вы это делаете, но я не смотрел подробно: если вы используете шаблон против другой таблицы, например, WHERE все равно будет медленным.

Кроме того, все те тесты, которые появляются перед «% ...», должны быть против столбцов с индексом, если вы хотите скорость в то время, когда вы выполняете SELECT (существует компромисс между индексами и выполнением много INSERT INTO, а не много SELECT.)

Смежные вопросы