Оптимизировать SQL запрос

237
26 ноября 2016, 20:16

В БД (в 5-ти таблицах одновременно, суммарно примерно 20000 строк) осуществляется живой поиск:

В зависимости от значения radio в форме осуществляется поиск по адресу, имени (полные Ф.И.О.) или телефону:

if ($radio == 'by_address') {
    $searchby = 'address';
    $key = '%' . $keywords . '%';
    $orderby = 'ORDER BY `address` ASC';
} elseif ($radio == 'by_name') {
    $searchby = 'name';
    $key = '%' . $keywords . '%';
    $orderby = 'ORDER BY `name` ASC';
} elseif ($radio == 'by_phone') {
    $searchby = 'phones';
    $key = $keywords . '%';
    $orderby = 'ORDER BY `phones` ASC';
} else {
    $searchby = 'address';
    $key = '%' . $keywords . '%';
    $orderby = 'ORDER BY `idnew` ASC';
}   

сам запрос:

SELECT * FROM (
    SELECT 
         id, (id + 100000) as idnew, name, address, phones, district 
    FROM $pack_bp
    UNION ALL
    SELECT
        id, (id + 100000) as idnew, name, address, phones, district 
    FROM $pack_lp
    UNION ALL
    SELECT
        id, (id + 100000) as idnew, name, address, phones, district 
    FROM $pack_rp
    UNION ALL
    SELECT
        id, (id + 100000) as idnew, name, address, phones, district 
    FROM $pack_dp
    UNION ALL
    SELECT
        id, (id + 100000) as idnew, name, address, phones, district    
    FROM $pack_cp           
) AS foo
WHERE 
    upper($searchby) LIKE  upper($key)
$orderby
LIMIT 
    0, $limit_results

Как оптимизировать запрос? Теперь поиск осуществляется очень долго секунд 20.

add:

  • upper - используется для того чтобы ввод в формуму запроса был регистро независимым для удобства.
  • 5 таблиц не объеденные в одну т.к. обновляются независимо друг от друга в разное время.
Answer 1
  1. Не вижу проблемы объединить таблицы в одну, как писали ранее.
  2. Если все оставлять также, ввиду известного параметра $searchby, можно селектить только из нужной таблицы. Например:

    if $searchby = 'by_adress' begin
      select * from $first_table where $blabla
    end
    else if $searchby = 'by_phone' begin
      select * from $second_table where $blabla
    end
    
  3. Проверить есть ли индексы, если нет - проставить.

  4. В переменные $pack_ХХ только название таблицы? Или там какой то набор таблица с джойнами? Если последнее - напишите какой.
  5. Если результат отображается пользователю. наверняка не нужны все записи таблицы, тогда используйте select top X * from
  6. Если сделав все, проблема останется - смотрите план запроса.
Answer 2

Поиск по всего лишь 20000 строк будет происходить практически мгновенно, если не копировать каждый все эти строки в новую таблицу, как это происходит сейчас.

Поэтому детский лепет про "обновление в разное время" надо забыть, сделать ОДНУ таблицу, и искать по ней.

Чтобы отличать разные источники, добавить в общую таблицу отдельное поле, в которое и писать все эти "лэпэ, рэпе и пэрэ". таким образом запрос

SELECT * FROM table WHERE type='lp' 

даст искомую таблицу "pack_lp" если вдруг понадобилось получить досуп к данным конкретного источника.

READ ALSO
Вывести только уникальные значения?

Вывести только уникальные значения?

Всем приветЕсть такой вот массив

233
Вывод из mySQL timestamp в UNIX виде

Вывод из mySQL timestamp в UNIX виде

В базе хранится дата и время в виде 2012-09-25 12:31:130 Правильно я понимаю, что на самом деле содержимое просто так отображается, но хранится в формате...

261
Таблицы html, вывод данных из бд в таблицу php

Таблицы html, вывод данных из бд в таблицу php

Когда я пытался вывести данные из таблицы в бд, в таблицу на странице сайта, то столкнулся нос в нос с проблемой вывода тк

508
Как изменять нужные данные в базе данных?

Как изменять нужные данные в базе данных?

Всем привет! Прошу прощения за глупую формулировку вопроса! Не придумал лучшеТяжело описать вопрос поэтому я его нарисовал) Надеюсь поймете!...

231