Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск по тексту в большой таблице 
:(
    Опции темы
niibaca
Дата 28.1.2008, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



Итак, следующая ситуация.

Есть 2 таблицы. Одна с ценами на товар, регулярно обновляется (100-300 тыс. строк).
А другая с моделями этого товара (несколько десятков тыс. строк). Для каждой модели мне надо знать кол-во предложений и минимальную цену.
Делаю это следующим образом. Беру название модели, засовываю в LIKE и пробегаю по названиям прайсовых строк в первой таблице.

На обновление информации для каждой модели уходит 0.6 секунды. В перспективе моделей может быть 100 000. То есть на обновление будет уходить сутки!!

Думал полнотекстовый поиск по индексу меня спасет, но он выдает совершенно неправильные результаты, а мне нужно строгое соответствие. 
Что посоветуете в данной ситуации? Какие приемы? Может использовать другую БД? Или другую структуру?

Это сообщение отредактировал(а) niibaca - 28.1.2008, 01:58
PM MAIL   Вверх
SelenIT
Дата 28.1.2008, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 9
Всего: 401



Нафиг в таблице с ценами название модели? По логике, там должен быть ее id. И вообще, я так и не понял, что и где обновляется, когда задача сформулирована как
Цитата(niibaca @  28.1.2008,  01:57 Найти цитируемый пост)
Для каждой модели мне надо знать кол-во предложений и минимальную цену
?


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
niibaca
Дата 28.1.2008, 02:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



Таблица с ценами - это распарсенные xml из разных источников.

Так понятнее?
PM MAIL   Вверх
SelenIT
Дата 28.1.2008, 02:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 9
Всего: 401



Немного, но хорошо бы привести полную структуру и примеры хотя бы пары типичных строчек для обеих таблиц.

Кстати, как связаны между собой "товар" и "модели"?


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
niibaca
Дата 28.1.2008, 02:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



Пример таблицы товары (offers)

of_id | of_name | of_price
123 | Nokia N95 | 567
345 | Apple iPhone | 1030
432 | Nokia 6300 | 234

Пример таблицы каталог (models)

md_id | md_brand  | md_name | md_amount | md_bestprice
123 | Nokia | N73 | 5 | 678
345 | Nokia | N82 | 10 | 567
432 | Nokia | N95 | 7 | 563

Вот скрипт, который отвечает за обновление.
Код

//Подготавливаем список моделей для сверки
$sql = "SELECT * FROM models";
$mydb->base_query($sql);
while ($row = $mydb->base_Fetch_Array()) { $models[$row["md_id"]] = $row["md_name"]; }

//Обнуляем кол-во предложений и минимальные цены
$sql = "UPDATE boo_models SET md_amount='0', md_bestprice='0'";
$mydb->base_query($sql);

//Поехали!
foreach ($models as $key => $msg)
{

  $sql2 = "SELECT of_price FROM offers";
  $sql2 .=" WHERE (of_name LIKE '%".$msg." %' OR of_name LIKE '%".$msg."')";
  $sql2 .=" ORDER BY of_price DESC";
  $mydb->base_query($sql2);
  $amount=$mydb->base_num_rows();
  while ($row = $mydb->base_Fetch_Array()) { $price = $row["of_price"]; }
    
  if ($amount != 0)
  {
      $sql = "UPDATE boo_models SET md_amount='".$amount."', md_bestprice='".$price."' WHERE md_name='".$msg."'";
      $mydb->base_query($sql);
  }
}


Добавлено через 2 минуты и 35 секунд
Самое узкое место получается здесь:
Код

  $sql2 = "SELECT of_price FROM offers";
  $sql2 .=" WHERE (of_name LIKE '%".$msg." %' OR of_name LIKE '%".$msg."')";
  $sql2 .=" ORDER BY of_price DESC";


На выборку из 100 000 строк уходит 0.6 секунды.
PM MAIL   Вверх
SelenIT
Дата 28.1.2008, 03:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 9
Всего: 401



Имхо, поля md_amount и md_bestprice в таблице models не нужны - их всегда можно посчитать в запросе на выборку. А вместо поля of_name я бы писал в таблицу offers значение md_id, соответствующее данной модели (получая его при добавлении данных, на этапе парсинга XML прайсов). Тогда нужная выборка делалась бы очень просто:

Код

SELECT CONCAT(m.md_brand,' ',m.md_name) as m_name, COUNT(o.of_id) AS m_amount, MIN(o.of_price) AS m_bestprice
FROM models AS m
INNER JOIN offers AS o USING md_id
GROUP BY m.md_brand, m.md_name


С правильными индексами должно работать очень быстро, тем более результаты частых запросов MySQL кеширует...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
niibaca
Дата 28.1.2008, 03:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



Спасибо, завтра попробую.

Только я не очень хорошо себе представляю, как найти по названию товара в прайсе модель из каталога. Когда в названии в прайсе стоит только "Nokia N95", то найти просто, а вот если "Сотовый телефон Nokia N95 красный"?
PM MAIL   Вверх
SelenIT
Дата 28.1.2008, 03:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 9
Всего: 401



Имхо, можно разбивать по словам и искать как-то наподобие
Код

... WHERE md_brand IN('Сотовый', 'телефон', 'Nokia', 'N95', 'красный') AND md_name IN('Сотовый', 'телефон', 'Nokia', 'N95', 'красный')


Для ускорения можно завести массив типичных классов товаров ("Сотовый телефон" и т.п.) и перед разбивкой их просто отрезать...


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
skyboy
Дата 31.1.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



а как насчет того, чтоб документы присылали корректно оформленными? или на источники данных ты не влияешь?
PM MAIL   Вверх
niibaca
Дата 31.1.2008, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



skyboy, не влияю.
PM MAIL   Вверх
niibaca
Дата 6.2.2008, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 24.1.2008

Репутация: нет
Всего: нет



Цитата

Имхо, можно разбивать по словам и искать как-то наподобие


Снова занялся этой проблемой, попробовал Ваш вариант. Он не подходит, если модель состоит из 2 слов. Например, Canon EOS 350D
Тогда он ищет IN('EOS', '350D') и конечно же ничего не находит.

Как еще можно подобный поиск выполнить без Like?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0700 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.