Оптимизация запросов PHP MySQL - PullRequest
1 голос
/ 13 марта 2011

Мне просто интересно, есть ли лучший способ сделать этот запрос?

$searchTerm = explode(' ', $search);
$wall_sql = "SELECT filename, category, name, downloads FROM wallpapers WHERE (pending='0' AND mediaType='0') AND ( ";
for($i=0;$i<count($searchTerm);$i++){
    if($i != 0){
        $wall_sql .= " OR ";    
    }
    $wall_sql .= " (category LIKE '%".$searchTerm[$i]."%') OR (filename LIKE '%".$searchTerm[$i]."%') OR (tags LIKE '%".$searchTerm[$i]."%') OR (name LIKE '%".$searchTerm[$i]."%') ";        
}
$wall_sql .= " ) ORDER BY ordernum DESC ";

Что делает этот скрипт, он берет в поисковом выражении $ search и разбивает его на массив с помощью функции разнесения в PHP. Затем я зацикливаюсь на этом массиве, чтобы создать запрос. Это единственный способ сделать это, я просто не уверен, что это лучший способ. Также будут ли какие-либо индексы работать с этим запросом, если да, то какими они будут?

Ответы [ 4 ]

1 голос
/ 13 марта 2011

Как вы описываете свою задачу, вы все делаете правильно. Индексы находятся вне окна, хотя, если вы используете LIKE "% search_term%".

Может немного изменить код для удобства чтения:

$searchTerm = explode(' ', $search);
foreach ($searchTerm as $s){
    $f[] = "category LIKE '%".$s."%'";
    $f[] = "filename LIKE '%".$s."%'";
    $f[] = "tags LIKE '%".$s."%'";
    $f[] = "name LIKE '%".$s."%'"; 
} 
$wall_sql = " 
SELECT filename, category, name, downloads   
  FROM wallpapers   
  WHERE pending='0' AND mediaType='0'
    AND (".implode(" OR ",$f).")   
ORDER BY ordernum DESC";
1 голос
/ 13 марта 2011

Ваш запрос не сможет использовать какие-либо индексы, а использование LIKE может дать ложные совпадения (например, поиск для x LIKE '%red%' будет соответствовать hired).

Если вы еще не рассмотрелиэто, возможно, вы захотите посмотреть полнотекстовый поиск , так как этот тип поиска может использовать индекс FULLTEXT.

0 голосов
/ 13 марта 2011

Я бы создал несколько виртуальных таблиц на основе условия поиска при объединении со столбцами таблиц.

Что-то вроде

SELECT w.filename, 
       w.category, 
       w.name, 
       w.downloads 
FROM   wallpapers w 
       LEFT JOIN (SELECT 'term1' AS name 
             UNION 
             SELECT 'term2' AS name 
             UNION 
             SELECT 'term3' AS name)  cat 
         ON cat.name = w.category 
       LEFT JOIN (SELECT 'filename1' AS name 
             UNION 
             SELECT 'filename2' AS name 
             UNION 
             SELECT 'filename3' AS name)  f 
         ON f.name = w.filename 
WHERE  w.pending = '0' 
         AND w.mediatype = '0' 
         AND (cat.name IS NOT NULL OR f.name IS NOT NULL)
GROUP by w.id
ORDER  BY w.ordernum DESC 

В этом случае вы динамически создаете значения виртуальной таблицы в виде статических жестко закодированных значений (term1,2,3 и filename1,2,3), и вам необходимо добавить индексы для следующих столбцов

  1. (в ожидании, MEDIATYPE)
  2. (ordernum)
  3. (категория)
  4. (имя файла)
  5. при условии, что у вас есть первичный ключ id
0 голосов
/ 13 марта 2011

Заданный вами запрос является обычным поисковым запросом, который может хорошо выполнять свою работу. Если вы хотите повысить производительность, вы можете добавить полнотекстовый индекс и использовать полнотекстовый поиск или использовать такой инструмент, как Sphinx . Sphinx индексирует вашу базу данных, поэтому полнотекстовый поиск становится очень быстрым. Однако вам необходимо установить и поддерживать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...