У меня есть 2 таблицы (companies и companies_locations) и очень простой запрос
SELECT
c.name,
(SELECT MIN(ST_Distance_Sphere(l.coords, POINT(4.985173, 45.001672)) from companies_locations l where l.companyId = c.id
FROM companies c
WHERE MATCH (c.name) AGAINST ('+rand*' IN BOOLEAN MODE)
Примечание: долгота, широта и полный текст задаются через параметры в моем коде
Примечание: там может бытьбыть множеством companies_locations для данной компании (отсюда минимум и подзапрос)
Теперь моя проблема: Я не понимаю, почему mysql не может использовать индекс покрытия для companies_locations (companyId, ords)
Вот подробности sql:
drop table IF exists companies;
drop table IF exists companies_locations;
CREATE TABLE `companies` (
`id` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx_ft_provider_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `companies_locations` (
`id` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
`companyId` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
`coords` point DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_providerId` (`companyId`,`coords`(25)),
KEY `idx_providerIdCoords` (`companyId`,`coords`(25))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO companies (id, name) ...;
INSERT INTO companies_locations (id, companyId, coords) ...;
explain SELECT
c.name,
(SELECT MIN(ST_Distance_Sphere(l.coords, POINT(4.985173, 45.001672))) from companies_locations l where l.companyId = c.id) as dist
FROM companies c
WHERE MATCH (c.name) AGAINST ('+rand*' IN BOOLEAN MODE)
План объяснения:
'1', 'PRIMARY', 'c', NULL, 'fulltext', 'idx_ft_provider_name', 'idx_ft_provider_name', '0', 'const', '1', '100.00', 'Using where; Ft_hints: no_ranking'
'2', 'DEPENDENT SUBQUERY', 'l', NULL, 'ref', 'idx_providerId,idx_providerIdCoords', 'idx_providerId', '162', 'beasyness.c.id', '1', '100.00', NULL
В ЗАВИСИМОЙ ПОДПИСИ я бы хотел, чтобы оптимизаторвыберите idx_providerIdCoords и «Using index: true»
Даже если я удаляю другой индекс, оптимизатор, похоже, по-прежнему делает «простую» ссылку (т.е. нужно перейти к таблице, чтобы прочитать координаты)