Задавайте вопросы, мы ответим
Вы не зашли.
Есть три таблички:
1. Таблица параметров товара.(Режим, Мощность, Вес) - item_params (id, class_id, name)
Где class_id - нужный мне вид товара.
2. Таблица значений параметров товара. (Холод и тепло, 5КВт, 15кг) - item_values (item_id, param_id, value)
3. Таблица самого товара. - items (id, name,class)
Делаю:
Отредактированно plazmagod (28.06.2011 14:31:38)
Неактивен
Попробуй так:
Неактивен
И EXPLAIN от запроса после замены
Неактивен
seekwell написал:
Попробуй так:
SELECT
i.name
FROM
items i
JOIN item_values iv ON i.id = iv.item_id AND
iv.value = "Холод и тепло"
JOIN item_params ip ON ip.param_id = iv.param_id AND
ip.class_id BETWEEN 1 AND 12 AND
ip.name = 'Режим'
;
Красиво.
Выдаёт 900 повторяющихся строк. Делаю DISTINCT, всё вроде верно, 75 строк.
Отредактированно plazmagod (28.06.2011 14:26:25)
Неактивен
А сколько строк выдает Ваш запрос? Неужели, другое?
Неактивен
paulus написал:
А сколько строк выдает Ваш запрос? Неужели, другое?
75 без DISTINCT. Но он настолько медленный, что использовать его совсем невозможно. 15-17 сек. для одного запроса на локальной машине - совсем никуда.
Кстати, я выше ему EXPLAIN подвесил. Можете на пальцах объяснить почему он долгий такой?
Отредактированно plazmagod (29.06.2011 09:01:16)
Неактивен
Попробуйте сделать таблицы временные через CREATE TEMPORARY TABLE и обязательно проиндексируйте поля, по которым идет JOIN
Неактивен
DanJer написал:
Попробуйте сделать таблицы временные через CREATE TEMPORARY TABLE и обязательно проиндексируйте поля, по которым идет JOIN
Спасибо. С этим
Неактивен
Давай те для начала посмотрим структуру ваших таблиц
Неактивен
Таблица items:
Отредактированно plazmagod (29.06.2011 12:43:29)
Неактивен
Если ничего не напутал то должно быть так:
Неактивен
А какие отличия от кода предложенного seekwell?!
seekwell написал:
Попробуй так:
SELECT
i.name
FROM
items i
JOIN item_values iv ON i.id = iv.item_id AND
iv.value = "Холод и тепло"
JOIN item_params ip ON ip.param_id = iv.param_id AND
ip.class_id BETWEEN 1 AND 12 AND
ip.name = 'Режим';
Ещё вопрос. Параметров может быть несколько: "Режим", "Вес", "Мощность". Значения их соответственно будут тоже разнотипными: "Холод и тепло", "15кг", "5КВт". Как в случае такого синтаксиса сделать запрос, сравнивающий в случае "Режим" текстовую строку, а в случае "Вес" и "Мощность" отсекали бы из string integer и сравнивали бы уже числом по величине?
Может действительно в этом случае временные таблицы были бы удобнее?
Неактивен
plazmagod написал:
А какие отличия от кода предложенного seekwell?!
Индексы.
plazmagod написал:
Ещё вопрос. Параметров может быть несколько: "Режим", "Вес", "Мощность". Значения их соответственно будут тоже разнотипными: "Холод и тепло", "15кг", "5КВт". Как в случае такого синтаксиса сделать запрос, сравнивающий в случае "Режим" текстовую строку, а в случае "Вес" и "Мощность" отсекали бы из string integer и сравнивали бы уже числом по величине?
Может действительно в этом случае временные таблицы были бы удобнее?
Не нужны вам временные таблицы, поставте индексы которые я вам написал и прешлите новый EXPLAIN.
Ещё зачем у вас стоит FULLTEXT KEY ? Бывают случаи когда вы ищите отдельные слова в тексте ? Если нет, то снимите его.
plazmagod написал:
"Режим", "Вес", "Мощность", "Холод и тепло", "15кг", "5КВт".
Почему вообще идёт запрос по словам а не изначально по id ?
У вас что в самом приложении на клиенте так обозначаются поля ?
Что то типо
Неактивен
поставте индексы которые я вам написал и прешлите новый EXPLAIN.
Проставил. Поля TEXT и TINYTEXT преобразовал в CHAR. Запрос выдал вообще все i.name таблицы items
EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE i ALL NULL NULL NULL NULL 3319 Using temporary
1 SIMPLE iv ref item_id_2 item_id_2 64 udb64.i.id,const 1 Distinct
1 SIMPLE ip ref id_2 id_2 4 udb64.iv.param_id 30 Using index; Distinct
Работающий код из #8 коммента выдал EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE i ALL PRIMARY NULL NULL NULL 3319 Using temporary
1 SIMPLE iv ref item_id_2 item_id_2 64 udb64.i.id,const 1 Using where; Distinct
1 SIMPLE ip ref id_2 id_2 4 udb64.iv.param_id 30 Using where; Using index; Distinct
FULLTEXT снял.
Почему вообще идёт запрос по словам а не изначально по id ?
C 1C в базу сайта характеристики объекта выгружается в виде произвольной пачки. Ни разделения по классам, ни унификации. XML-файл товаров примерно похож на этот select.
Неактивен
Запрос выдал вообще все i.name таблицы items
И это означает что в вашем запросе точно нету DISTINCT-а
SELECT DISTINCT i.name
FROM items i
JOIN item_values iv ON i.id = iv.item_id
AND iv.value = "Холод и тепло"
JOIN item_params ip ON ip.id = iv.param_id
AND ip.class_id
BETWEEN 1
AND 12
AND ip.name = 'Режим'
+
Индексы
(i.name)
(iv.item_id,iv.value)
(ip.id, ip.class_id, ip.name)
Запрос и структуру в студию:
SHOW CREATE TABLE items;
SHOW CREATE TABLE item_values;
SHOW CREATE TABLE item_params;
Отредактированно evgeny (29.06.2011 18:01:03)
Неактивен
Вот этот запрос нормально отработал. Его EXPLAIN:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE i ALL PRIMARY NULL NULL NULL 3319 Using temporary
1 SIMPLE iv ref item_id_2 item_id_2 64 udb64.i.id,const 1 Using where; Distinct
1 SIMPLE ip ref id_2 id_2 4 udb64.iv.param_id 30 Using where; Using index; Distinct
Таблица items:
Неактивен