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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не используется индекс, ORDER BY по полю присоединённой таблицы 
V
    Опции темы
DCoder
Дата 4.9.2010, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Доброго времени суток!
У меня имеется 2 таблицы: элементы и значения свойств этих элементов.
Код

CREATE TABLE `elements` (
  `id` int NOT NULL,
  `name` text NOT NULL,
  `xml_id` text,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `properties` (
  `property_id` int NOT NULL,
  `value` text(20),
  `element_id` int NOT NULL,
  PRIMARY KEY  (`element_id`,`property_id`),
  KEY `ind_prop_el_val1` (`element_id`,`property_id`,`value`(20))
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


Хочу отсортировать по полю присоединённой таблицы:
Код

select 
    el.id, el.name, prop1.VALUE as value1, prop2.VALUE as value2
from
    elements as el
    left join properties as prop1 on el.id = prop1.element_id
    left join properties as prop2 on el.id = prop2.element_id
where
    prop1.property_id = 83 AND prop2.property_id = 84
order by
    prop2.value ASC
limit 10


Задумывается очень-очень крепко...

Вот, что говорит explain:
Код

1    SIMPLE    el    ALL    PRIMARY                                            358400    Using temporary; Using filesort
1    SIMPLE    prop1    ref    PRIMARY,ind_prop_el_val1    ind_prop_el_val1    8    bitrix.el.id,const    1    Using where
1    SIMPLE    prop2    eq_ref    PRIMARY,ind_prop_el_val1    PRIMARY            8    bitrix.el.id,const    1    Using where


Подскажите пожалуйста, как оптимизировать?
PM MAIL   Вверх
Akina
Дата 4.9.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Код

select 
    el.id, el.name, prop1.VALUE as value1, prop2.VALUE as value2
from
    elements as el
    left join properties as prop1 on el.id = prop1.element_id and prop1.property_id = 83
    left join properties as prop2 on el.id = prop2.element_id and prop2.property_id = 84
order by
    prop2.value ASC
limit 10
А если так?


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

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


Шустрый
*


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

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



Akina,
Пробовал - 51 сек. smile
Цитата

Никогда не следует указывать в части ON какие бы то ни было условия, накладывающие ограничения на строки в наборе результатов. Если необходимо указать, какие строки должны присутствовать в результате, следует сделать это в выражении WHERE. 
 По рекомендации http://www.mysql.ru/ перенёс всё это дело в WHERE.

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


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


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

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



Цитата(DCoder @  4.9.2010,  19:44 Найти цитируемый пост)
Задумывается очень-очень крепко...

Цитата(DCoder @  4.9.2010,  20:27 Найти цитируемый пост)
Пробовал - 51 сек.

А если в поддающихся сравнению единицах?


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

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


Шустрый
*


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

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



Цитата(Akina @  4.9.2010,  22:26 Найти цитируемый пост)
А если в поддающихся сравнению единицах? 

Хм... Сам не понял, что повлияло на результаты, но таблицы и индексы остались прежними, а время выполнения запросов 16.55684 мой вариант и 17.43842 Ваш.

Наверно, вся беда в Using temporary; Using filesort?
PM MAIL   Вверх
Zloxa
Дата 5.9.2010, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(Akina @  4.9.2010,  18:57 Найти цитируемый пост)
А если так? 

Не эквивалентно же!!!

Попробуйте составной индекс по properties (property_id,value) 
И если он сам не поймет в какой последовательности правильно джойнить - попробуйте определить порядок соединения непосредственно в запросе. /*к сожалению я не знаю как подсказать масиному оптимизаторов, что последовательность жойнов следует выдержать именно в порядке, определенном запросом*/
Код

select 
    el.id, el.name, prop1.VALUE as value1, prop2.VALUE as value2
from
     properties as prop2
    inner join  elements as el on el.id = prop2.element_id
    inner join properties as prop1 on prop2.element_id = prop1.element_id
where
    prop1.property_id = 83 AND prop2.property_id = 84
order by
    prop2.value ASC
limit 10



Это сообщение отредактировал(а) Zloxa - 5.9.2010, 13:16


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


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


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

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



Цитата(Zloxa @  5.9.2010,  13:58 Найти цитируемый пост)
я не знаю как подсказать масиному оптимизаторов, что последовательность жойнов следует выдержать именно в порядке, определенном запросом

Да как обычно - расставить скобки.
Цитата(Zloxa @  5.9.2010,  13:58 Найти цитируемый пост)
Не эквивалентно же!!!

угу, есть такое


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

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


Чо?
****


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

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



Цитата(Akina @  5.9.2010,  15:46 Найти цитируемый пост)
Да как обычно - расставить скобки.

Я это к тому, что Оракля, к примеру, чхал на скобки, для него хинтовать приходится, чтоб он этого не делал ;)
А как дела в масе обстаят, ей богу не знаю.


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


Шустрый
*


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

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



Zloxa, 14.31255 сек.
EXPLAIN:
Код

1    SIMPLE    prop2    ref    PRIMARY,ind_prop_el_val,ind_prop_pid_value    ind_prop_pid_value    4    const    322440    Using where; Using filesort
1    SIMPLE    el    eq_ref    PRIMARY    PRIMARY    4    bitrix.prop2.element_id    1     
1    SIMPLE    prop1    eq_ref    PRIMARY,ind_prop_el_val,ind_prop_pid_value    PRIMARY    8    bitrix.prop2.element_id,const    1

Если я не ошибаюсь, то сортировать, используя индекс, он не будет, потому что поле value имеет тип TEXT. Как-нибудь можно избавиться от filesort?


Цитата(Zloxa @  5.9.2010,  12:58 Найти цитируемый пост)
Не эквивалентно же!!!

А нескромный вопрос... Почему не эквивалентно?

Это сообщение отредактировал(а) DCoder - 5.9.2010, 16:17
PM MAIL   Вверх
Zloxa
Дата 5.9.2010, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(DCoder @  5.9.2010,  16:13 Найти цитируемый пост)
EXPLAIN

К сожалению я так и не научился читать масин эксплайн.
Индекс какой используется - ind_prop_pid_value?
Похоже - да.
Цитата(DCoder @  5.9.2010,  16:13 Найти цитируемый пост)
Почему не эквивалентно?

потому что критерии отбора перенесены в критерии объединения.
Запрос, переписанный Akina вернет ВСЕ элементы, а Ваш только те, для которых определены свойства. 
Цитата(DCoder @  5.9.2010,  16:13 Найти цитируемый пост)
то сортировать, используя индекс, он не будет, потому что поле value имеет тип TEXT

тут не знаю. Весьма вероятно. пусть знающие подскажут.



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


Шустрый
*


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

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



Заменил тип данных поля value с TEXT на varchar(255) - время выполнения скрипта 0.19693 сек.
EXPLAIN:
Код

1    SIMPLE    prop2    ref    PRIMARY,ind_propid_value    ind_propid_value    4    const    322440    Using where; Using index
1    SIMPLE    el    eq_ref    PRIMARY    PRIMARY    4    bitrix.prop2.element_id    1     
1    SIMPLE    prop1    eq_ref    PRIMARY,ind_propid_value    PRIMARY    8    bitrix.prop2.element_id,const    1

Но! Стоит увеличить длину varchar(500), как индекс уже не используется, и возвращается filesort. Кто-нибудь может внести ясность?
PM MAIL   Вверх
Zloxa
Дата 6.9.2010, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(DCoder @  5.9.2010,  21:40 Найти цитируемый пост)
Но! Стоит увеличить длину varchar(500), как индекс уже не используется, и возвращается filesort. Кто-нибудь может внести ясность? 

не связано ли это с ограничением длины строки, хранимой в индексе?
Цитата

А prefix can be up to 1000 bytes long for MyISAM tables, and 767 bytes for InnoDB tables.

тут.
Если индекс хранит не строку целиком, а лишь ее префикс, индекс не может быть использован для сортировки.

ЗЫ И, конечно, я проглядел что у Вас value имеет тип TEXT. Для меня наличие необходимости сортировки по значению поля этого типа - разрыв шаблона. Быть может стоит подумать о суррогатном поле, которое хранило бы префикс строки, заполнялось бы из триггера, было бы проиндексировано и использовалось бы для сортировки?

Это сообщение отредактировал(а) Zloxa - 6.9.2010, 11:19


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


Чо?
****


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

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



а что, кстати означает text(10)?
1) что поле вмещает лишь 10 символов
2) что в таблице хранятся первые 10 символов, а остальные хранятся гдето с боку


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


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


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

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



Цитата(Zloxa @  6.9.2010,  12:23 Найти цитируемый пост)
а что, кстати означает text(10)?

Ни то, ни другое. Это означает, что следует использовать наименьший из типов семейства TEXT, который вмещает указанное количество символов. В данном случае это будет TINYTEXT, макс. длина которого 255 символов.


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

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


Шустрый
*


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

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



Zloxa
Akina
Извиняюсь за долгое отсутствие!

Структура немного изменилась, и я думал, что уже вроде всё заработало, но тут у меня возник вообще ступор  smile 
Может сегодня я уже заработался или звёзды не так сошлись... Создаю уже такой дубовый пример:
Код

create table test_table (
    id int not null primary key,
    int_field1 int,
    int_field2 int,
    KEY ind_int_field1 (int_field1)
);

INSERT test_table VALUES (1, 453, 2343), (2, 445, 23432), (5, 234, 7686734);

EXPLAIN SELECT * FROM test_table ORDER BY int_field1;


Вот что заявляет мне explain:
Код

+----+-------------+------------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+------------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | test_table | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+------+----------------+


Возможных ключей нет, и ключ не используется!!! Как это понимать? Я уже несколько часов с ним воюю...
Если подставить FORCE INDEX (ind_int_field1), то он его будет использовать, но если попробовать к этой таблице присоединить какую-нибудь другую, то даже FORCE INDEX ему не указ.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




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


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

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