Модераторы: 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   Вверх
Akina
Дата 21.9.2011, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



z-END, а где в catalog_item_options индекс по item_id?
И с какой великомудрой целью там индекс (option_id, item_id)? уж лучше бы наоборот...



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

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


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


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

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



это через JOIN


Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  var1.PNG 15,00 Kb


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

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


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


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

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



это where

Добавлено через 7 минут и 12 секунд
Цитата(Akina @  21.9.2011,  15:44 Найти цитируемый пост)
И с какой великомудрой целью там индекс (option_id, item_id)? уж лучше бы наоборот...

не знал, что в составном индексе - порядок играет роль. 
поменял местами 
Цитата(Akina @  21.9.2011,  15:44 Найти цитируемый пост)
а где в catalog_item_options индекс по item_id?

добавил

вариант с JOIN:  строки 0 - 29 (50,000 всего, запрос занял 13.0903 сек.)
вариант с WHERE: строки 0 - 29 (30 всего, запрос занял 29.9699 сек.)



Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  var2.PNG 12,27 Kb


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

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


Бывалый
*


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

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



Просто для интереса, что нибудь измениться если запрос написать, примерно так:
Код

SELECT T1. *
FROM catalog_items AS T1
JOIN 
(SELECT item_id FROM catalog_item_options WHERE
(T2.option_id =35 AND T2.value =145)
OR (T2.option_id =36 AND T2.value = 'red')
GROUP BY item_id
HAVING COUNT( item_id ) >2) AS T2 ON ( T2.item_id = T1.id )
WHERE ( T1.list_id =6 AND T1._visible =1)
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30

или так  smile 
Код

SELECT T1. *
FROM catalog_items AS T1
WHERE ( T1.list_id =6 AND T1._visible =1)
AND
(SELECT COUNT(item_id) FROM catalog_item_options AS T2 WHERE
T2.item_id = T1.id AND
((T2.option_id =35 AND T2.value =145)
OR (T2.option_id =36 AND T2.value = 'red')))>2
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30

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


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


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

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



AndreyIQ,  первый вариант 
Цитата

Отображает строки 0 - 29 (50,000 всего, запрос занял 2.0857 сек.)
SELECT T1. *
FROM catalog_items AS T1
JOIN (

SELECT item_id
FROM catalog_item_options AS T2
WHERE (
T2.option_id =35
AND T2.value =145
)
OR (
T2.option_id =36
AND T2.value = 'red'
)
GROUP BY item_id
HAVING COUNT( item_id ) >2
) AS T2 ON ( T2.item_id = T1.id )
WHERE (
T1.list_id =6
AND T1._visible =1
)
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30



второй вариант.
Цитата

Отображает строки 0 - 29 (50,000 всего, запрос занял 29.1533 сек.)
SELECT T1. *
FROM catalog_items AS T1
WHERE (
T1.list_id =6
AND T1._visible =1
)
AND (

SELECT COUNT( item_id )
FROM catalog_item_options AS T2
WHERE T2.item_id = T1.id
AND (
(
T2.option_id =35
AND T2.value =145
)
OR (
T2.option_id =36
AND T2.value = 'red'
)
)
) >2
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30


сейчас заметил, что при добавлении данных в цикле по ошибке все даннные добавил два раза, по этому HAVING COUNT(item_id) получается не 2 а 4. это может быть проблемой?

Добавлено через 4 минуты и 50 секунд
Цитата(z-END @  21.9.2011,  17:04 Найти цитируемый пост)
2.0857 сек.

это уже интересно, но все равно от заявленных: 

Цитата(Akina @  21.9.2011,  13:18 Найти цитируемый пост)
запрос должен работать на уровне десятков мс

 очень далек... 


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

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


Бывалый
*


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

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



Если не ошибаюсь то от лимита Вы скорость не выиграете, т.к. используется группировка и сортирока, а для них необходимо сначала выбрать все данные.
PM MAIL   Вверх
z-END
Дата 21.9.2011, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



LIMIT   phpmyadmin автоматом добавляет, но он касается только вывода данных. проверял без него - скорость та же... 

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


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

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


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


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

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



z-END, давайте так - Вы не валите всё в кучу в хрен знает какой форме, а чётко даёте группу (show create table + explain select). И не из ПХПадмина, а с консоли сервера - нас ведь интересует происходящее именно на сервере, верно?



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

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


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


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

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



Akina,  да босс))) дам все что угодно=))

T1
Цитата

| catalog_items | 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 AUTO_INCREMENT=66040 DEFAULT CHARSET=utf8 |


T2
Цитата

| catalog_item_options | 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` (`item_id`,`option_id`),
  KEY `item_id` (`item_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1540198 DEFAULT CHARSET=utf8 |


эксплейны каких запросов ?


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

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


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


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

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



Цитата(z-END @  21.9.2011,  21:33 Найти цитируемый пост)
эксплейны каких запросов ? 

Тех, скорость которых не устраивает, которые надо оптимизировать.

Добавлено @ 22:11
Да! explain не на пустых таблицах, пожалуйста, а на заполненных. Данными в количестве и соотношениях, приблизительно соответствующих реально-боевым.


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

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


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


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

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



Потыкался еще, так к гармонии и не пришел... 
может перед эксплейнами все таки убедится в правильности структуры.


1. база данных содержит данные о разных видах изделий, каждый вид изделий имеет свой набор опций.  
2. виды изделий  должны иметь возможность модифицироваться в процессе штатной эксплуатации. (т.е. могут добавляться или удалятся опции)

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


общие для всех видов опции:
- ID
- страна_производитель
- название
- тэги 
- цена
- производитель
- наличие 
- тип изделия
- популярность изделия
- дата обновления данных

виды расширенных опций:
тип (1): ДВИГАТЕЛЬ
1. тип (3-цилиндровый(1), 4-цилиндровый(2), 6 цилиндровый(3), 8-цилиндровый(4), роторный(5))
2. вес (int)
4. удельная мощность (int)
5. впрыск (карбюратор(1), инжектор(2))
6. топливо (бензин(1), дизель(2))
7. опции: (система старт/стоп(1); система отключения цилиндров(2);)

тип (2): КПП
8. тип (механика(1), автомат(2), вариатор(3), робот(4), dsg(5))
9. количество передач (int) 

тип (3): ТОРМОЗНАЯ СИСТЕМА
10. передние тормоза (дисковые(1), барабанные(2))
11. опционал передних тормозов (вентилируемые(1); перфорируемые(2))
12. задие тормоза (дисковые(1), барабанные(2))
13. опционал задних тормозов (вентилируемые(1); перфорируемые(2))
14. опционал тормозов (ABS(1); EBD(2); HillAssist(3),AutoHandbrake(4))

опции могут быть:
 - для каждого изделия подходит только один из возможных вариантов - впрыск двигателя(5) может быть ИЛИ карбюратор ИЛИ инжектор)
 - для каждого изделия может подходить как множество опций, так и ни одной - тормоза (14) могут быть И ABS И EBD И HA и AH. 


Поисковая задача должна реализвоать поиск следующего вида:

Необходимо найти все изделния из разделов Двигатели(1) и Тормозная система(3):
- от производителей АА или ББ
- находящиеся в наличии
- произведенные германии 
- нужны двигатели(1):
- - 6 цилиндровые (опция1=6)
- - инжектор (опция5=2)

- нужны тормозные системы(3):
- - передние тормоза дисковые (опция10=1)
- - задние торомза дисковые (опция12=1)
- - опционал тормозов ABS, EBD и HillAssist (опция14=1 + опция14=2 + опция14=3)

сейчас есть две таблицы catalog_items - которые хранят общие данные об изделиях  и таблица catalog_item_options в которых хранятся данные о опциях каждого изделия, допустим у нас есть тормозная система с:

10. передними тормозами дисковыми (1)
11. передние тормоза вентилируемые(1), перфорируемые(2)
12. задние барабанные (2)
14. абс(1) и HillAssist(3)

то в базу catalog_item_options данные заносятся
|--item_id--|--option_id--|--value--|
|---xxxx----|------10-----|---1-----| // дисковые
|---xxxx----|------11-----|---1-----| //вентидлируемые
|---xxxx----|------11-----|---2-----| //перфорируемые
|---xxxx----|------12-----|---2-----| //задний барабан
|---xxxx----|------14-----|---1-----| //ABS
|---xxxx----|------14-----|---3-----| //HillAsist

так вот, может уже на этом этапе не правильная логика процесса?

PS более того, изначально я рассматривал частный случай поиска по одному виду изделий, а требуется поиск различных (двигатель и тормоза в одном запросе)




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

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


Бывалый
*


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

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



Цитата(z-END @ 23.9.2011,  12:52)
общие для всех видов опции:
- ID
- страна_производитель
- название
- тэги 
- цена
- производитель
- наличие 
- тип изделия
- популярность изделия
- дата обновления данных

виды расширенных опций:
тип (1): ДВИГАТЕЛЬ
1. тип (3-цилиндровый(1), 4-цилиндровый(2), 6 цилиндровый(3), 8-цилиндровый(4), роторный(5))
2. вес (int)
4. удельная мощность (int)
5. впрыск (карбюратор(1), инжектор(2))
6. топливо (бензин(1), дизель(2))
7. опции: (система старт/стоп(1); система отключения цилиндров(2);)

тип (2): КПП
8. тип (механика(1), автомат(2), вариатор(3), робот(4), dsg(5))
9. количество передач (int) 

тип (3): ТОРМОЗНАЯ СИСТЕМА
10. передние тормоза (дисковые(1), барабанные(2))
11. опционал передних тормозов (вентилируемые(1); перфорируемые(2))
12. задие тормоза (дисковые(1), барабанные(2))
13. опционал задних тормозов (вентилируемые(1); перфорируемые(2))
14. опционал тормозов (ABS(1); EBD(2); HillAssist(3),AutoHandbrake(4))

На мой взглад вполне нормальная структура.
PM MAIL   Вверх
z-END
Дата 23.9.2011, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


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

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


Чо?
****


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

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



Цитата(z-END @  21.9.2011,  16:39 Найти цитируемый пост)
LIMIT   phpmyadmin автоматом добавляет, но он касается только вывода данных. проверял без него - скорость та же... 

Лимит в продуктивном решении предполагается?
Или пользователю все 50 тыщ покзать надо?

Цитата(AndreyIQ @  21.9.2011,  16:31 Найти цитируемый пост)
используется группировка и сортирока, а для них необходимо сначала выбрать все данные

в точку!

Группировки тут  можно избежать используя семиджойны:

Код

select * 
from catalog_items AS T1
where  T1.list_id =6 AND T1._visible =1
  and exists (select null from  catalog_item_options AS T2_1  where  T2_1.item_id = T1.id AND T2_1.option_id =35  AND T2_1.value =145)
  and exists (select null from  catalog_item_options AS T2_2  where  T2_2.item_id = T1.id AND T2_2.option_id =36 AND T2_2.value = 'red')
ORDER BY T1._ratio DESC , T1._updated DESC , T1.id DESC
LIMIT 0 , 30

добавить индекс по catalog_item_options (item_id,option_id,value)

Пересмотреть порядок сортировки, чтобы не было desc, создать индекс на catalog_items(list_id,_visible,... поля сортировки). 

Если порядок сортировки надо выдержать именно этот - лепить костыли:
в catalog_items  добавить поля __ratio, __updated, _id. Заполнять из триггера значениями соотвественных полей умноженных на -1, включить их в индекс и сортироваться по ним asc

Форсить использование этих индексов.

Зачем, думаю, понятно. Чтобы избежать необходимости сортировки, заменить ее на сканирование индекса. Это возможно лишь когда у нас есть составной индекс, где сначала перечислены столбцы, по которым производится отбор, а затем поля сортировки в том порядке, в котором они перечислены в ордербай. Так же нужно следить, чтобы порядок сортировки не зависел от параметров сессии (языкове настройки, регистонезависмые сортировки, бинарные/лингвистические сортировки и т.п.), тогда индекс не сможет быть использован. Полагаю таймстамп - не тот случай.

Если нам удастся использовать индекс вместо ордербая, запрос будет мухой работать, когда без лимита из 60 тыщ будут выбираться 50 тыщ. Однако в случае, если без лимита под критерии будет попадать лишь одна запись, да в самом конце отсортированного списка... будут те же 20 сек


А вообще проблема типична. С ней в конце концов сталкиваются все любители гибких подходов. Реляционные базы любят четкость и определенность. Если атрибут используется логикой приложения, по нему производится отбор, он должен быть столбом таблицы, а не UDA


Это сообщение отредактировал(а) Zloxa - 28.9.2011, 09:31


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
z-END
Дата 27.9.2011, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



привет осень... первый больничный в самом разгаре))) 

Цитата(Zloxa @  24.9.2011,  03:27 Найти цитируемый пост)
Лимит в продуктивном решении предполагается?Или пользователю все 50 тыщ покзать надо?

для пользователя будет организована постраничная навигация.
 

Zloxa, спасибо! как в норму приду буду изучать изложенное..

Цитата(Zloxa @  24.9.2011,  03:27 Найти цитируемый пост)
А вообще проблема типична. С ней в конце концов сталкиваются все любители гибких подходов. Реляционные базы любят четкость и определенность. Если атрибут используется логикой приложения, по нему производится отбор, он должен быть столбом таблицы, а не UDA

вот и я смотрел в эту сторону, но умные люди отговаривают... 


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

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


Чо?
****


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

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



Цитата(z-END @  27.9.2011,  19:12 Найти цитируемый пост)
для пользователя будет организована постраничная навигация.

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

Цитата(z-END @  27.9.2011,  19:12 Найти цитируемый пост)
но умные люди отговаривают...  

Тогда не слушай умных, спрашивай глупых, но опытных. smile 


Это сообщение отредактировал(а) Zloxa - 28.9.2011, 10:43


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


 




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


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

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