Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.03.2012, 13:44   #1
Dexes
Пользователь
 
Регистрация: 27.12.2011
Сообщений: 86
По умолчанию Оптимизация функций.

Добрый день.
Поставлена задача оптимизировать две функции. Поизвращаться над ними уже успел, заработали быстрее но недостаточно быстро, больше не знаю что делать...
PHP код:
function check_category_by_name ($name) {
    global 
$link$mc_array;
    
$id 0;
    
    foreach (
$mc_array as $key => $value) {
        
$pos strpos($key$name);
        if (
$pos !== false) {
            return 
$mc_array[$key];
        }
    }
    
    return 
$id;

$mc_array выглядит примерно так

PHP код:
Array
(
    [
Мобильные телефонысотовый телефон] => 3063
    
[Мобильные телефоныкоммуникатор] => 3064
    
[Телефонияфаксытелефон PANASONIC KX-TG] => 3065
    
[Телефонияфаксытелефон PHILIPS CD] => 3065
    
[Телефонияфаксытелефон TEXET TX-D] => 3065
    
[Телефонияфаксытелефон VOXTEL Combo] => 3065
    
[Телефонияфаксытелефон VOXTEL Elegant] => 3065
    
[Телефонияфаксытелефон VOXTEL Profi] => 3065
    
[Телефонияфаксытелефон VOXTEL Select] => 3065
    
[Телефонияфаксытелефон VOXTEL Symphony] => 3065
    
[Телефонияфаксытелефон VOXTEL Wall] => 3065
    
[Телефонияфаксыдоп.трубка] => 3066
    
[Телефонияфаксырадиостанция] => 3067
    
[Телефонияфаксытелефон] => 3068
    
[Телефонияфаксытелефонный адаптер] => 3068
    
[Телефонияфаксытелефонный коннектор] => 3068
    
[Телефонияфаксытелефонный переходник] => 3068
    
[ТелефонияфаксыТелефонная гарнитура] => 3068
    
[Аксессуары к сотовымBluetooth] => 3069
    
[ТелефонияфаксыGSM-шлюз] => 3070
    
[Телефонияфаксымини АТС] => 3071
    
[ТелефонияфаксыТермо-пленка] => 3072
    
[ТелефонияфаксыТонер] => 3072

Только там пара сотен элементов
Мне не важно что в нем после ";". Важно совпадение данных до точки с заяптой с входящей в функцию переменной $name.
Как только нашли такое совпадение функция возвращает value и финита.

PHP код:
function check_category_by_name ($name) {
    global 
$link$mc_array;
    
$id 0;
    
    foreach (
$mc_array as $key => $value) {
        
$pos explode(';'$key);
        if (
$pos[0] == $name) {
            return 
$mc_array[$key];
        }
    }
    
    return 
$id;

Такой вариант обрабатывает дольше.

вторая функция, самая дикая

PHP код:
function check_product_by_name ($name$category_id 0) {
    global 
$link;
    
    
$row = array('product_id' => 0);
    
$sql 'select product_id, model, model2, model3, model4, model5 from product where category_id = '.$category_id;
    
$query mysql_query ($sql$link) or sql_error ($sql$link__FILE____LINE__);
    while (
$row mysql_fetch_assoc($query)) {
        
$pos strpos($row['model'], $name);
        if (
$pos === false) {
            
$pos strpos($row['model2'], $name);
        }
        else {
            return 
$row;
        }
        if (
$pos === false) {
            
$pos strpos($row['model3'], $name);
        }
        else {
            return 
$row;
        }
        if (
$pos === false) {
            
$pos strpos($row['model4'], $name);
        }
            else {
            return 
$row;
        }
        if (
$pos === false) {
            
$pos strpos($row['model5'], $name);
        }
        else {
            return 
$row;
        }
        if (
$pos !== false) {
            return 
$row;
        }
    }
    return 
$row;

Запросили из базы все модели товаров из раздела, если нашли вхождение модели (или альтернативного названия модели) в входящем значении $name вылетаем из функции возвращая product_id.
Как можно оптимизировать эти две дико жрущие серверные ресурсы вещи?
Dexes вне форума Ответить с цитированием
Старый 05.03.2012, 14:10   #2
Cronos20
Форумчанин
 
Регистрация: 08.07.2010
Сообщений: 679
По умолчанию

Это все очень просто решается средствами самой базы данных
1. Неправильное проектирование БД - нужно все ваши model1, model2 ... 4,5 вынести в отдельную таблицу ( TABLE models (product_id, model_name) )
2. Расставить индексы
3. Простой поиск по моделям с JOIN и like
Код:
select ... from product JOIN models WHERE models.model_name like '%....%'
Может я не до конца понял код, ввиду очень плохой читабельньности ваших функций, я не вдавался в подробности ваших циклов перебора. Но мне кажется, все решается вполне просто.
Cronos20 вне форума Ответить с цитированием
Старый 05.03.2012, 14:13   #3
Dexes
Пользователь
 
Регистрация: 27.12.2011
Сообщений: 86
По умолчанию

like - есть плохо.
Если при "=" mysql работает с индексами, то с like скула начинает работать уже со значениями, и врят ли многим отличается от strpos.

-- ADD --

С базой я к сожалению ничего не могу сделать, с какой дали работать, с той и приходится.

Последний раз редактировалось Dexes; 05.03.2012 в 14:21.
Dexes вне форума Ответить с цитированием
Старый 05.03.2012, 14:48   #4
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,160
По умолчанию

а может как вариант
Код:
select product_id, model, model2, model3, model4, model5 from product where category_id = '.$category_id && (model like %$name% || model2 like %$name% || model3 like %$name% || model4 like %$name% || model5 like %$name%)
или
Код:
select product_id, model, model2, model3, model4, model5 from product where category_id = '.$category_id && concat(model, model1, model2, model3, model4,model5) like %$name%
а вообще - лучше реально поменять структуру БД
like - не всегда есть плохо
отличаться будет тем что нагрузка будет на БД ... снижая скорость.. во втором случае - нагрузка на PHP код ... то есть память и процессор
ADSoft вне форума Ответить с цитированием
Старый 05.03.2012, 14:50   #5
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,160
По умолчанию

в вашем случае вытаскивать ВСЮ базу и конопатить её - ужасно!
а если записей тысячи? миллионы?
ADSoft вне форума Ответить с цитированием
Старый 05.03.2012, 14:54   #6
Dexes
Пользователь
 
Регистрация: 27.12.2011
Сообщений: 86
По умолчанию

Здесь не like нужен, а ему обратный)))
не
model like %$name%
а
$name like %model%
Если можно так выразиться)

Цитата:
Сообщение от ADSoft Посмотреть сообщение
в вашем случае вытаскивать ВСЮ базу и конопатить её - ужасно!
а если записей тысячи? миллионы?
Записей может быть до тысячи, всё же ограничить вывод через category_id было неплохим решением)))
про вытаскивание согласен, но и поменять структуру БД не в моей компетенции...

Последний раз редактировалось Dexes; 05.03.2012 в 15:04.
Dexes вне форума Ответить с цитированием
Старый 05.03.2012, 15:06   #7
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,160
По умолчанию

ну поменяй на обратный.... пусть $name like %model%
только тогда второй способ не подойдет точно )
ADSoft вне форума Ответить с цитированием
Старый 05.03.2012, 15:19   #8
Dexes
Пользователь
 
Регистрация: 27.12.2011
Сообщений: 86
По умолчанию

Не знал что так можно... (чего по молодости только не узнаешь)
Dexes вне форума Ответить с цитированием
Старый 05.03.2012, 15:25   #9
Cronos20
Форумчанин
 
Регистрация: 08.07.2010
Сообщений: 679
По умолчанию

Никогда не понимал логика заказчика, который просит чего-то там наоптимизировать в скриптах, когда БД изначально сделана через одно место и ее трогать почему-то нельзя )
Хотя скрипт конвертации данных из одной таблицы в 3 другие пишется за пару минут. Думаю самый простой способ - убеждать заказчиков в неизбежности нормальной оптимизации начиная с корня проблемы.

P.S. Советую для скорости это все выполнять в хранимой процедуре, потому что их вызов хорошо кэшируется
Cronos20 вне форума Ответить с цитированием
Старый 05.03.2012, 15:37   #10
Dexes
Пользователь
 
Регистрация: 27.12.2011
Сообщений: 86
По умолчанию

Я не общаюсь напрямую с заказчиком. Мне ставят задачу написать/оптимизировать модуль, я делаю) Не более того.
Dexes вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi: аппроксимация функций методом базиса из финитных функций Denna Помощь студентам 1 12.03.2012 19:23
Численные методы : Оптимизация функций одной переменной Дырдин Общие вопросы C/C++ 1 04.04.2011 11:36
Оптимизация... MikeMNN Общие вопросы C/C++ 0 15.12.2010 17:40
Построение графиков функций С++ (методы аппроксимации функций) amdbodia Общие вопросы C/C++ 0 24.05.2009 15:28
использование функций в качестве параметров других функций mono Помощь студентам 0 20.04.2009 18:25