mysql - MySQL Optimizer 对相同查询的意外结果?
问题描述
以下查询按预期工作并使用索引查询需要 0,0481 秒
SELECT
geodb_locations.name,
geodb_locations.name_url,
COUNT(user.uid) AS useranzahl
FROM
user
LEFT JOIN
geodb_locations ON geodb_locations.id=user.plz
WHERE
user.freigeben=1 AND
geodb_locations.adm0='AT'
GROUP BY user.plz
ORDER BY useranzahl DESC
LIMIT 25
如果在查询中仅更改国家/地区区域设置,则从 AT 到 DE 查询大约需要 2.5 秒并且不使用索引
SELECT
geodb_locations.name,
geodb_locations.name_url,
COUNT(user.uid) AS useranzahl
FROM
user
LEFT JOIN
geodb_locations ON geodb_locations.id=user.plz
WHERE
user.freigeben=1 AND
geodb_locations.adm0='DE'
GROUP BY user.plz
ORDER BY useranzahl DESC
LIMIT 25
为什么第二个查询的优化器不使用索引以及如何改进查询。2.5 秒太长了..
解决方案
如果u.uid
不能NULL
,请使用COUNT(*)
代替COUNT(u.uid)
。
正如已经指出的,删除LEFT
.
添加这些索引:
user: (freigeben, plz)
geodb_locations: (adm0, name_url, name)
至于为什么要EXPLAIN
更改,... 常量的分布确定触摸表的顺序(奥地利不如德国常见?)或使用哪个索引是很正常的(但有些罕见)。
不管优化如何,这个查询必须为 DE 扫描比 AT 多得多的行;这必须发生在 sort ( ORDER BY
) 和LIMIT
.
有两件事阻止了很多优化:
- 引用这
WHERE
两个表。 ORDER BY
取决于计算值。