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

Поиск:

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


 




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


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

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