Поисковый запрос с join

marv255
Дата: 18.12.2012 15:25:40
Здравствуйте. Никак не могу сообразить как провести поиск по подстроке.

Есть таблица с объектами:
objects (
	id INT(10),
	number VARCHAR(255),
	name VARCHAR(255)
)

Есть таблица со свойствами объектов, у одного объекта может быть несколько свойств, поэтому связь один ко многим:
properties (
	id INT(10),
	object_id INT(10),
	name VARCHAR(255),
	value VARCHAR(255)
)

Нужно найти объект по его свойствам, например, все объекты зеленого цвета. С одним словом ищу так:
SELECT o.id 
FROM objects o
LEFT JOIN properties p ON p.object_id = o.id
WHERE p.value LIKE 'зелен%'

А теперь надо сделать такой же поиск но уже по двум свойствам, например, все круглые объекты зеленого цвета:
SELECT o.id 
FROM objects o
LEFT JOIN properties p ON p.object_id = o.id
WHERE p.value LIKE 'зелен%' AND p.value LIKE 'кругл%'

Последний запрос не возвращает ничего. Если использую OR, тогда возвращаются и круглые и зеленые, это не подходит, нужно именно пересечение.
Как в данном случае провести поиск по двум/трем/четырем словам?
qwerty112
Дата: 18.12.2012 15:42:02
marv255,

тут - 13569655 несколько вариантов
marv255
Дата: 19.12.2012 11:58:37
qwerty112
marv255,

тут - 13569655 несколько вариантов

Спасибо. Сделал так:

SELECT DISTINCT `o`.`number`
FROM `objects` `o`
JOIN `properties` `cd0` ON cd0.value LIKE '%nissan%'
JOIN `properties` `cd1` ON cd1.value LIKE '%tiida%' AND cd1.object_id = cd0.object_id
JOIN `properties` `cd2` ON cd2.value LIKE '%20%' AND cd2.object_id = cd1.object_id
WHERE cd2.object_id = o.id AND o.name = 'car'
DESC LIMIT 50

Вроде относительно быстро работает, учитывая, что там таблица 30-40 тысяч свойств.

Еще два вопроса:

- Имеет ли смысл делать индекс на properties.value? В этой таблице очень много записей, но все значения короткие 5-7 символов.

- Как в этом же запросе достать либо nissan tiida, либо просто все записи с пометкой new_car? Пробовал переделать запрос, но скрипт вываливается по таймауту:

SELECT DISTINCT `o`.`number`
FROM `objects` `o`
JOIN `properties` `cd0` ON cd0.value LIKE '%nissan%'
JOIN `properties` `cd1` ON cd1.value LIKE '%tiida%' AND cd1.object_id = cd0.object_id
JOIN `properties` `cd2` ON cd2.value LIKE '%20%' AND cd2.object_id = cd1.object_id
WHERE (cd2.object_id = o.id AND o.name = 'car') OR o.name = 'new_car'
DESC LIMIT 50
marv255
Дата: 19.12.2012 14:48:38
Индексы ничего не изменили, только сильно увеличили объем таблицы. С этим разобрался.

А вот по второму вопросу все таки непонятно. Если оставляю join, то выбираются new_car только среди nissan tiida, это понятно. А вот если меняю join на left join, тогда такой запрос напрочь вешает сервер.