Структура таблицы:
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`from` int(10) unsigned NOT NULL,
`to` int(10) unsigned NOT NULL,
`message` text NOT NULL,
`sent` int(10) unsigned NOT NULL DEFAULT '0',
`read` tinyint(1) unsigned NOT NULL DEFAULT '0',
`direction` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `one` (`to`,`direction`,`from`,`id`),
KEY `two` (`from`,`direction`,`to`,`id`),
KEY `three` (`read`,`direction`,`to`),
KEY `four` (`read`,`direction`,`from`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
У меня странная проблема. Посмотрите следующий запрос:
select test.id, test.from, test.to, test.message, test.sent, test.read, test.direction from test
where (
(test.to = 244975 and test.direction <> 2 and test.direction <> 3 and
(
(test.from = 204177 and test.id > 5341203) OR
(test.from = 214518 and test.id > 5336549) OR
(test.from = 231429 and test.id > 5338284) OR
(test.from = 242739 and test.id > 5339541) OR
(test.from = 243834 and test.id > 5340438) OR
(test.from = 244354 and test.id > 5337489) OR
(test.from = 244644 and test.id > 5338572) OR
(test.from = 244690 and test.id > 5338467)
)
)
or
(test.from = 244975 and test.direction <> 1 and test.direction <> 3 and
(
(test.to = 204177 and test.id > 5341203) OR
(test.to = 214518 and test.id > 5336549) OR
(test.to = 231429 and test.id > 5338284) OR
(test.to = 242739 and test.id > 5339541) OR
(test.to = 243834 and test.id > 5340438) OR
(test.to = 244354 and test.id > 5337489) OR
(test.to = 244644 and test.id > 5338572) OR
(test.to = 244690 and test.id > 5338467)
)
)
or
(test.read <> 1 and test.direction <> 3 and test.direction <> 2 and test.to = 244975 and test.from not in (204177, 214518, 231429, 242739, 243834, 244354, 244644, 244690)
)
or
(test.read <> 1 and test.direction = 2 and test.from = 244975 and test.to not in (204177, 214518, 231429, 242739, 243834, 244354, 244644, 244690)
)
)
order by test.id;
Если я объясню этот запрос, он пройдет через все строки:
1 SIMPLE test index PRIMARY,one,two,three,four PRIMARY 4 1440596 Using where
Если я удалю оба оператора "не в", то он отлично работает:
select test.id, test.from, test.to, test.message, test.sent, test.read, test.direction from test
where (
(test.to = 244975 and test.direction <> 2 and test.direction <> 3 and
(
(test.from = 204177 and test.id > 5341203) OR
(test.from = 214518 and test.id > 5336549) OR
(test.from = 231429 and test.id > 5338284) OR
(test.from = 242739 and test.id > 5339541) OR
(test.from = 243834 and test.id > 5340438) OR
(test.from = 244354 and test.id > 5337489) OR
(test.from = 244644 and test.id > 5338572) OR
(test.from = 244690 and test.id > 5338467)
)
)
or
(test.from = 244975 and test.direction <> 1 and test.direction <> 3 and
(
(test.to = 204177 and test.id > 5341203) OR
(test.to = 214518 and test.id > 5336549) OR
(test.to = 231429 and test.id > 5338284) OR
(test.to = 242739 and test.id > 5339541) OR
(test.to = 243834 and test.id > 5340438) OR
(test.to = 244354 and test.id > 5337489) OR
(test.to = 244644 and test.id > 5338572) OR
(test.to = 244690 and test.id > 5338467)
)
)
or
(test.read <> 1 and test.direction <> 3 and test.direction <> 2 and test.to = 244975
)
or
(test.read <> 1 and test.direction = 2 and test.from = 244975
)
)
order by test.id;
Теперь запрос объяснения возвращает:
1 SIMPLE test index_merge PRIMARY,one,two,three,four one,two 5,5 30 Using sort_union(one,two); Using where; Using filesort
Я не уверен, почему это не работает. Что мне не хватает в индексах?