2016-04-08 3 views
0

Я хочу хранить несколько MPTT (модифицированных деревьев предзаказов) в одной таблице MySQL со следующими столбцами: node_id, user_id, rht, lft, значение. Единое дерево назначается одному пользователю на веб-сайте.Использование вложенного запроса для улучшения производительности SELECT в MySQL

Чтобы выбрать дерево из указанного узла для пользователя Я хотел бы использовать:

SELECT * FROM categories 
WHERE user_id = 123 
AND lft > node_lft 
AND rht < node_rht; 

Я думаю об использовании вложенного запроса для этой функции:

SELECT t.* FROM 
(SELECT * FROM categories WHERE user_id = 123) t 
WHERE lft > node_lft 
AND rht < node_rht; 

Какой из запросов работает быстрее при работе на большие данные (например, 10000 пользователей, у каждого есть одно дерево со случайной глубиной и количеством элементов) и почему?

ответ

2

Не используйте вложенные подзапросы в условии FROM в MySQL, если у вас нет действительно веской причины. MySQL реализует такие подзапросы. Помимо накладных расходов, это также предотвращает использование индексов для объединений.

Вместо этого просто определите правильный индекс на таблице. На основании Вашего запроса:

categories(user_id, lft, rht) 
0

Любой индекс, начиная с user_id будет полезно для любого запроса. Предоставьте SHOW CREATE TABLE.

Без подзапроса:

INDEX(user_id, lft) (или INDEX(user_id, rht)) будет сканировать, возможно, половину из user_id=123 строк; небольшое улучшение по сравнению с просто INDEX(user_id). Из-за «диапазона» (lft > nodelft), (user_id, lft, rht), индекс с тремя колонками проходит через диапазон на lft; следовательно, не выгодно.

С подзапроса:

  1. извлечь все строки с user_id=123; положить в таблицу tmp.
  2. Сканируйте эту таблицу tmp. Нет индекса полезен.

Подзапрос не может быть быстрее. Если да, то может быть, что была разница в том, что было кэшировано, когда вы проводили тесты времени.

Насколько велика таблица? Насколько велик кеш (innodb_buffer_pool_size, если InnoDB)? Если таблица слишком велика, тогда «ленивый поиск» может быть оправдан.

Используете ли вы node_id для чего-нибудь? Является ли это комбо уникальным: (user_id, lft, rht); если так, то это может быть PRIMARY KEY. (Доступ через ПК мы обычно быстрее, чем через дополнительный ключ в InnoDB.)

Смежные вопросы