2016-01-25 5 views
1

У меня есть данные, которые структурированы следующим образом:Оптимизация медленного запроса MySQL с Самосоединением

Parent | Child 
散  | ⺙ 
⺙  |  
⺙  | 乂 
散  | 龷 
散  | 月 

Я использую следующий запрос, чтобы вернуть все предок до двух уровней выше термина поиска (то есть, возвращать родителей и бабушек и дедушек).

SELECT a.parent AS level3, b.parent AS level2, c.parent AS level1 
FROM decomposition_dup AS a 
LEFT JOIN decomposition_dup AS b ON a.parent LIKE b.child 
LEFT JOIN decomposition_dup AS c ON b.parent LIKE c.child 
WHERE a.child LIKE '$searchterm' 

Проблема в том, что это довольно медленный запрос (~ 5 секунд). Мои EXPLAIN показывает:

enter image description here

Я уже проиндексированы соответствующие столбцы. Я сделал ошибку? Или есть лучший способ структурировать мой запрос?

EDIT: Вот структура таблицы:

CREATE TABLE `decomposition_dup` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`parent` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, 
`structure` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, 
`child` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, 
PRIMARY KEY (`id`), 
KEY `parent` (`parent`), 
KEY `child` (`child`), 
KEY `parent_2` (`parent`,`child`) 
) ENGINE=InnoDB AUTO_INCREMENT=211929 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 
+0

В таблицах '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' '' '' '' '' '' '' '' '' имеет номер продукта, который довольно большой. Поэтому я не беспокоюсь о вашем рабочем времени. –

+0

@TimBiegeleisen - Это все та же таблица. У меня сложилось впечатление, что ~ 165 000 строк - это не большой стол? –

+0

Хорошо, если вам нужно сравнить записи «150K +» с «150K +» записями, это важно. Вы уверены, что используются индексы? –

ответ

0
  1. LIKE в =
  2. Набор COLLATE utf8mb4_unicode_520_ci на parent и child, если вы хотите 'похожих' символы, которые будут рассматриваться равное. Или используйте COLLATE utf8mb4_general_ci для них неравномерно. Example of such
0

Ваш запрос в порядке. Он использует соответствующие индексы для b и c (USING INDEX), но может однако быть улучшена путем добавления индекс покрытия на

(`a.`.parent, a.`child`) 

Моя гипотеза состоит в том, что фаза проекции занимает много времени, а не время вычисления (поскольку есть много записей до выход). Вы можете проверить самостоятельно с помощью mysql profiling.


О LIKE против = поведение «проблема», я столкнулся с той же проблемой сам в последнее время и вы можете наслаждаться читать дальше об этом there.