![]() |
Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте! Помогите, пожалуйста, разобраться со следующей проблемой.
Имеются две таблицы:
Обычная таблица (ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_bin):
Отредактированно FiMko (11.03.2012 02:27:33)
Неактивен
Подзапрос определяется как зависимый (DEPENDENT SUBQUERY), т.е. выполняется для каждой строки основного запроса. Соответственно индекс использован быть не может (possible_keys = null). Но так как вы выбираете только поле word, по которому есть индекс, то выборка идет по нему (type = index) Отсюда и появляются (key = word и rows = 4), так как идет full scan всего индекса.
Эту багу пока исправили только в MariaDB 5.3
В остальных случаях подзапросы в in нужно переписывать через join.
Неактивен
vasya написал:
В остальных случаях подзапросы в in нужно переписывать через join.
vasya, большое Вам спасибо! Join действительно помог.
Неактивен
Появился еще вопрос по индексам. Есть простая таблица:
Отредактированно FiMko (11.03.2012 18:45:56)
Неактивен
Добавьте индексы (col1,col3) и (col2,col3).
Посмотрите http://dev.mysql.com/doc/refman/5.5/en/ … ation.html
У вас в таблице слишком мало данных, чтобы изучать выбор оптимизатором того или иного плана.
P.S. Приводите, плиз, структуру таблицы не как "describe table1;"
а
mysql> show create table table1;
Неактивен
Что касается переписать на union без подзапросов, то что-то вроде
SELECT qwe FROM table2
JOIN table1 ON table2.col2 = table1.col2 WHERE (col1 = 2 AND col3 = 2)
union all
SELECT qwe FROM table2
JOIN table1 ON table2.col2 = table1.col2 WHERE (col2 = 2 AND col3 = 1)
Но это лучше оставить на потом.
Неактивен
vasya написал:
У вас в таблице слишком мало данных, чтобы изучать выбор оптимизатором того или иного плана.
Нет, в "продакшн" таблицах с ~80000 работает также, выше я привел некий тестовый пример.
vasya написал:
P.S. Приводите, плиз, структуру таблицы не как "describe table1;"
а
mysql> show create table table1;
Спасибо, буду знать на будущее. Вот структура:
vasya написал:
Добавьте индексы (col1,col3) и (col2,col3).
Добавил индексы, не помогло:
Отредактированно FiMko (11.03.2012 19:16:15)
Неактивен
Хм, у меня на таблице в 32 строки показывает range по col3
Неактивен
vasya написал:
Хм, у меня на таблице в 32 строки показывает range по col3
mysql> explain SELECT id FROM test WHERE (col1 = 2 AND col3 = 2) OR (col2 = 2 AN
D col3 = 1)\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: range
possible_keys: col1_col2_col3,col1,col2,col3,col1_3,col2_3
key: col3
key_len: 4
ref: NULL
rows: 2
Extra: Using where
1 row in set (0.00 sec)
Ммм... У меня MySQL ver. 5.5.13, может влиять? А range уже приемлемый вариант связывания? Для UNION ref использовался.
mysql.ru написал:
range: При помощи индекса для выборки строк будут извлечены только строки, находящиеся в заданном диапазоне. Используемый индекс указывается в столбце key. Столбец key_len содержит самую длинную часть ключа, которая была использована. Столбец ref будет содержать значения NULL для этого типа.
---
Перепроверил, да, у меня type все еще index для 33-х строк ...
Отредактированно FiMko (11.03.2012 19:43:22)
Неактивен
Версия может влиять, у меня 5.1
range означает, что по индексу будут выбраны строки, удовлетворяющие col3 = 2 or col3 = 1 и для них проверяется where
Если кардиналити col3 высокая, то можно указать использовать этот индекс с помощью
..FROM test use undex(col3)..
Неактивен
vasya написал:
Версия может влиять, у меня 5.1
range означает, что по индексу будут выбраны строки, удовлетворяющие col3 = 2 or col3 = 1 и для них проверяется where
Если кардиналити col3 высокая, то можно указать использовать этот индекс с помощью
..FROM test use undex(col3)..
Спасибо за помощь! Буду смотреть, что можно придумать...
Неактивен
Кстати, по вопросу различия планов выполнения. Дело не в версиях, а в разных наборах данных и как следствие разных кардиналити индекса col3.
Изначально, только две строки из 32 удовлетворяли условию col3 = 2 or col3 = 1 и выбирался range по col3. Если же уменьшить кардиналити col3, то будет full scan.
Неактивен
vasya написал:
Кстати, по вопросу различия планов выполнения. Дело не в версиях, а в разных наборах данных и как следствие разных кардиналити индекса col3.
Изначально, только две строки из 32 удовлетворяли условию col3 = 2 or col3 = 1 и выбирался range по col3. Если же уменьшить кардиналити col3, то будет full scan.
Угу, понял. Пока переделал на UNION, стало в ~1,5 раза быстрее.
Неактивен