我已经创建了一个产生正确结果的查询,但它正在执行全表扫描并创建一个临时表。 (使用临时;使用文件排序)。
我希望它使用索引,但是因为我使用 group by 来删除重复项,所以它不使用可用的索引。我试过删除 Group By 并使用 Distinct,但这并不能解决问题。
我使用的是多对多关系,因为一个员工可以有多个职位,多个员工可以有相同的职位。
表格:
CREATE TABLE IF NOT EXISTS `Employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(50) DEFAULT NULL,
`middlename` varchar(7) DEFAULT NULL,
`lastname` varchar(50) DEFAULT NULL,
`city` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `firstname` (`firstname`),
KEY `middlename` (`middlename`),
KEY `lastname` (`lastname`),
KEY `city` (`city`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `Employee_Position` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`employee_id` int(11) NOT NULL,
`position_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `employee_id` (`employee_id`),
KEY `function_id` (`position_id`),
KEY `employee_id+position_id` (`employee_id`,`position_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `Positions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
查询:
SELECT
e.id,
e.firstname,
e.middlename,
e.lastname,
e.city
FROM Employees AS e
INNER JOIN Employee_Position AS ep
ON e.id = ep.employee_id
WHERE (ep.position_id IN (1, 2, 3, 4))
GROUP BY e.id
ORDER BY e.lastname
为什么要创建一个临时表而不使用索引?有什么办法可以解决这个问题吗?
最佳答案
您的查询进行了不必要的聚合。
这里有一个更好的表达查询的方式:
SELECT e.id, e.firstname, e.middlename, e.lastname, e.city
FROM Employees e
WHERE EXISTS (SELECT 1
FROM Employee_Position ep
WHERE e.id = ep.employee_id AND ep.position_id IN (1, 2, 3, 4)
)
ORDER BY e.lastname;
您已经在 employee_position(employee_id, position_id)
上为该查询创建了正确的索引。
关于MySQL:Inner Join with Group By 正在创建一个临时表(进行表扫描),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49991914/