Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> выборка по множественному условию 
:(
    Опции темы
z-END
Дата 20.9.2011, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



приветствую! 
впал в творческий ступор, требуется имерженси хелп)

таблица (Т1)  вида:
|-- ID --|-- TITLE --|

таблица Т2 вида:
|-- ID --|-- ITEM_ID --|-- OPTION_ID --|-- VALUE --|

в таблице Т1 хранятся названия элементов, Т2 - содержит набор данных для элементов Т1.

нужно выбрать все записи из Т1, которые удовлетворяют условию запроса.  
запрос  формируется на основе массива связок вида  T2.option_id=$val  

пока ничего в голову, кроме цикличного JOIN-а всех опций не приходит.. 
например у нас есть массив условий:
Код

$search=array(
25="'new'",
144=15,
150="10,11,12"
)


то запрос для него формируется следующего вида:
Код

SELECT 
T1.id
FROM Table1 as T1,
JOIN Table2 as T2_1 ON (T2_1.item_id=T1.id AND T2_1.option_id=25 AND T2_1.value IN ('new')
JOIN Table2 as T2_2 ON (T2_2.item_id=T1.id AND T2_2.option_id=144 AND T2_1.value IN (15)
JOIN Table2 as T2_3 ON (T2_3.item_id=T1.id AND T2_3.option_id=150 AND T2_1.value IN (10,11,12)


что мне кажется крайне не эффективным способом... особенно если опций будет около 10, а запрос этот будет многократно вызываться...  

или может имеет смысл делать единую таблицу Т1 т Т2 со всеми опциями?  ( описывал тут



--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
AndreyIQ
Дата 20.9.2011, 14:03 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ИМХО JOIN'ы лучше не использовать, лучше через where
Код

SELECT 
T1.id
FROM Table1 as T1
JOIN Table2 as T2_1 ON T2_1.item_id=T1.id
WHERE
   (T2_1.option_id=25 AND T2_1.value IN ('new'))
    or
   (T2_2.option_id=144 AND T2_1.value IN (15))
   or
   (T2_3.option_id=150 AND T2_1.value IN (10,11,12))

PS Какая-то у Вас извращенная задача стоит.
PM MAIL   Вверх
z-END
Дата 20.9.2011, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



Цитата(AndreyIQ @  20.9.2011,  15:03 Найти цитируемый пост)
лучше через where

ваш запрос выведет все записи, для которых совпала ХОТЬ одна опция... 

Цитата(AndreyIQ @  20.9.2011,  15:03 Найти цитируемый пост)
PS Какая-то у Вас извращенная задача стоит.

а что в ней извращенного? 
обычный поиск  по базе данных =)


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Akina
Дата 20.9.2011, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

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



Цитата(z-END @  20.9.2011,  18:23 Найти цитируемый пост)
ваш запрос выведет все записи, для которых совпала ХОТЬ одна опция... 

Добавьте к нему
Код

GROUP BY T1.id
HAVING COUNT(T1.id)=3



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
z-END
Дата 20.9.2011, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



AndreyIQ,  
таблица Т2 содержит данные такого вида:

|-- ID --|-- ITEM_ID --|---- OPTION_ID ----|----- VALUE --|
|-- 1 ---|------- 1 ------|--- (1)материал ---|--- металл --|
|-- 2 ---|------- 1 ------|--- (1)материал ---|--- карбон --|
|-- 3 ---|------- 1 ------|--- (2)давление ---|----- 2.5 -----|
|-- 4 ---|------- 1 ------|----(3)сечение ----|------- 50-----|
|-- 5 ---|------- 2 ------|--- (1)материал ---|-- пластик --|
|-- 6 ---|------- 2 ------|--- (2)давление ---|----- 2.5 -----|

а поисковый запрос:

материал='металл,алюминий',
давление=2.5

соответственно выбрать нужно все ITEM_ID  для которых выполняется условие:
материал=(метал или аллюминий) и давление=(2.5)  (в этом примере получается только ITEM_ID=1 т.к. у ITEM_ID=2 материал не удовлетворяет условию: 'металл или алюминий',

Добавлено @ 17:52
Цитата(Akina @  20.9.2011,  18:29 Найти цитируемый пост)
HAVING COUNT(T1.id)=3

мои весьма поверхностные  знания  mysql почему-то говорят мне что такая операция - выполняется  как бы "вторым кругом" т.е. сначала выполняется выборка без этого условия, и уже потом выполняется выборка еще раз в полученном результате.

это я к тому а не устанет ли mysql перебирать такие объемы данных  (около миллиона записей в таблице Т1 и на каждую из них приходится в среднем 10 записейв в Т2 - тоесть 10 миллионов.  


Это сообщение отредактировал(а) z-END - 20.9.2011, 17:52


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Akina
Дата 20.9.2011, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

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



Цитата(z-END @  20.9.2011,  18:46 Найти цитируемый пост)
а не устанет ли mysql перебирать такие объемы данных  

А вот это уже не твоя забота... если ему станет плохо - он скажет.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
z-END
Дата 20.9.2011, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



Цитата(Akina @  20.9.2011,  22:03 Найти цитируемый пост)
А вот это уже не твоя забота


как раз тики моя))) если он будет это медленно выполнять все придется переделывать...


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Akina
Дата 21.9.2011, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

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



z-END, хватит ваньку-то валять. Вот КОГДА будет выполняться медленно - ТОГДА и будем думать над увеличением производительности. Но если ты заранее изучишь план выполнения и построишь необходимые для оптимизации индексы (с учётом наполнения и селективности) - это ТОГДА так и не наступит.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
z-END
Дата 21.9.2011, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



Akina, ответ достойный советского автопрома)))) 
давайте сделаем ладу-приору, а там уж если будет кривая, будем думать))))


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Akina
Дата 21.9.2011, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

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



z-END, если ты изначально намерен выпускать лады-приоры - может, задуматься о перепрофилировании завода вообще? или закрыть его к чёртовой матери?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
AndreyIQ
Дата 21.9.2011, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



У Вас большое кол-во OPTION_ID?
PM MAIL   Вверх
z-END
Дата 21.9.2011, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



AndreyIQ
в базе будет хранится порядка 100 видов, для каждого вида есть свой набор опций - в среднем порядка 10 шт.  получается что option_id - будет около 1000.


Цитата(Akina @  21.9.2011,  11:11 Найти цитируемый пост)
если ты изначально намерен выпускать лады-приоры - может, задуматься о перепрофилировании завода вообще? или закрыть его к чёртовой матери?

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


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Akina
Дата 21.9.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

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



Цитата(z-END @  21.9.2011,  11:33 Найти цитируемый пост)
пытаюсь понять наиболее оптимальный вариант

Оптимальный вариант - это правильное построение схемы данных, структур таблиц и индексов. 10кк записей - не так уж и много. А если селективность запроса высока - так и вовсе ерунда. Лишь бы не нарываться на прямой просмотр или там файловое кэширование. Но на поставленной задаче и описанной структуре как раз всего этого быть не должно, и запрос должен работать на уровне десятков мс.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
z-END
Дата 21.9.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

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



Цитата(Akina @  21.9.2011,  13:18 Найти цитируемый пост)
Оптимальный вариант - это правильное построение схемы данных, структур таблиц и индексов.

приветствую вас Капитан Очевидность)
именно этот вопрос я и пытаюсь понять:

-стоит ли использовать общую таблицу доп. данных или создавать отдельные таблицы с учетом структуры (как это в битриксе например делается)
-если использовать общую таблицу: как оптимально выбирать данные, с учетом большой детальности запроса

применительно к текущей ситуации - добавил 1.5 млн строк в Т2  и около 60 тыс в Т1.  

цифры меня шокировали... 
мой вариант:
Цитата

Отображает строки 0 - 29 (50,000 всего, запрос занял 15.6098 сек.)
SELECT T1 . *
FROM catalog_items AS T1
JOIN catalog_item_options AS T2_1 ON ( T2_1.item_id = T1.id AND T2_1.option_id =35  AND T2_1.value =145 )
JOIN catalog_item_options AS T2_2 ON ( T2_2.item_id = T1.id AND T2_2.option_id =36 AND T2_2.value = 'red' )
WHERE (T1.list_id =6 AND T1._visible =1)
GROUP BY T1.id
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30


вариант с where на 4 сек. медленней
Цитата

Отображает строки 0 - 29 (50,000 всего, запрос занял 19.9063 сек.)
SELECT T1. *
FROM catalog_items AS T1
JOIN catalog_item_options AS T2 ON ( T2.item_id = T1.id )
WHERE ( T1.list_id =6 AND T1._visible =1)
AND 
(
(T2.option_id =35 AND T2.value =145)
OR (T2.option_id =36 AND T2.value = 'red')
)
GROUP BY T1.id
HAVING COUNT( T1.id ) >2
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30


вот структура таблиц:
Т1
Код

CREATE TABLE `catalog_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `region_id` int(10) unsigned NOT NULL,
  `list_id` int(10) unsigned NOT NULL,
  `brand_id` int(10) unsigned NOT NULL,
  `price` float NOT NULL,
  `available` tinyint(1) NOT NULL,
  `title` varchar(150) NOT NULL,
  `tags` text NOT NULL,
  `img_count` tinyint(2) NOT NULL DEFAULT '0',
  `_visible` tinyint(1) NOT NULL DEFAULT '0',
  `_ratio` tinyint(2) unsigned NOT NULL,
  `_updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  `_created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `list_id` (`list_id`),
  KEY `_visible` (`_visible`),
  KEY `available` (`available`),
  KEY `region_id` (`region_id`),
  KEY `_ratio` (`_ratio`),
  KEY `brand_id` (`brand_id`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;



Т2
Код

CREATE TABLE `catalog_item_options` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `item_id` int(10) unsigned NOT NULL,
  `option_id` int(10) unsigned NOT NULL,
  `value` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `option_id` (`option_id`,`item_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;


Профилирование дает приблизительно такой результат: 
Цитата

starting  0.000093
Opening tables  0.000014
System lock  0.000004
Table lock  0.000006
init  0.000047
optimizing  0.000019
statistics  0.000353
preparing  0.000040
Creating tmp table  0.001950
executing  0.000002
Copying to tmp table  19.638440
Sorting result  0.067851
Sending data  0.001524
end  0.000002
removing tmp table  0.005356
end  0.000008
query end  0.000003
freeing items  0.000114
logging slow query  0.000002
logging slow query  0.000002
cleaning up  0.000003





--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
AndreyIQ
Дата 21.9.2011, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Хотелось бы еще план увидеть
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




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


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

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