如何索引 - 优化这个 MySQL 查询?
Posted
技术标签:
【中文标题】如何索引 - 优化这个 MySQL 查询?【英文标题】:How can I index - optimize this MySQL query? 【发布时间】:2017-03-15 15:52:09 【问题描述】:我有一个这样的查询:
SELECT id, terrain, occupied, c_type
FROM map
WHERE x >= $x-$radius
AND x <= $x+$radius
AND y >= $y-$radius
AND y <= $y+$radius
ORDER BY
x ASC,
y ASC
我的桌子是这样的:
CREATE TABLE `map` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`occupied` tinyint(2) NOT NULL DEFAULT '0',
`c_type` tinyint(4) NOT NULL DEFAULT '0',
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`terrain` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4_general_ci
我删除了除 PRIMARY KEY 之外的所有索引,因为我不确定索引如何与 SQL 一起使用。 我可以做些什么来调整这个查询?谢谢...
这不是重复的,检查 cmets!
【问题讨论】:
见***.com/questions/3567981/how-do-mysql-indexes-work How do MySQL indexes work?的可能重复 当您使用 WHERE 语句数据库按您指定的字段搜索数据时。所以你可以在'x'和'y'中添加索引。 。 @AlexSlipknot 如果我想完全避免表扫描,您能否展示一下索引的外观?比如,我应该按什么顺序放置 x、y、id、占用列等,以便优化器有效地使用它? @MetalCastles -INDEX(x,y,id)
-- id
没有添加任何有用的东西。拥有所有列(因此“覆盖”)可能是好的。然而,正如 SolarBear 指出的那样,“批量可能会减慢速度”。
【参考方案1】:
查询可以做到的最好的事情是
INDEX(x, y) -- In this order
这将是有效的
WHERE x >= $x-$radius
AND x <= $x+$radius
但不适用于过滤y
。
它会(可能)避免ORDER BY x ASC, y ASC
的“文件排序”。请注意,索引顺序必须与此顺序匹配。
为任何尝试的SELECT
提供EXPLAIN SELECT ...
。
并且,请在 MyISAM 被移除之前切换到 InnoDB。
Here 是一本关于 MySQL 索引的快速指南。
【讨论】:
我创建了索引gmp (x, y, id, terrain, occupied, c_type)
,并在上面的查询中运行 EXPLAIN 显示 id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE map range gmp gmp 8 NULL 1955 Using where;使用索引【参考方案2】:
所以,我添加了索引 gmp
与列 x, y, id, terrain, occupied, c_type
和 EXPLAIN SELECT 显示:
id: 1
select_type: SIMPLE
table: map
type: range
possible_keys: gmp
key: gmp
key_len: 8
ref: NULL
rows: 1955
Extra: Using where; Using index
所以,我想它现在可以工作了。
【讨论】:
以上是关于如何索引 - 优化这个 MySQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章