我对这个还是很困惑。这是来自在线问题集。
假设我有表 USER、CHECKIN 和 PLACE。
USER(uid, uname, ucity),uid为主键。
PLACE(pid, pname, pxcoord, pycoord, pcity),pid为主键。
CHECKIN (uid, pid, cdate, ctime),(uid, cdate, ctime)为主键。
查询是
select c.uid, c.pid c.cdate
from user u natural join checkin c natural join place p
where ucity='NewYork' and pcity='Chicago'
我可能对这个定义有一些误解。但最多只允许创建两个索引结构,有序索引和B+树索引该如何选择?
对于 checkin 表,我们应该创建两个索引(uid、pid)吗?如果是的话,作为主索引还是辅助索引有什么区别吗?
我在这里复制了原始问题
“假设对于每个查询,您最多可以创建两个索引结构以使查询更快,您将创建什么索引结构,以及这将如何改变评估计划和运行时间(换句话说,获取单个记录具有使用这些索引的特定非键值)。”
最佳答案
“没有人”使用NATURAL JOIN
。请更改为 JOIN ... ON ...
语法,以便您明确了解表之间的关联方式。另外,请为每个表提供SHOW CREATE TABLE
。
“只有2个索引结构”?你是在哪里拿到的? InnoDB“需要”一个主键
和最多64个“辅助键”。 PRIMARY KEY
与数据一起存储并以这种方式对数据进行排序。辅助键中包含主键,因此它们会进行第二次查找以获取数据。主键和辅助键都是 BTree 结构。
根据 MySQL 的定义,PRIMARY KEY
是 UNIQUE
和一个索引。因此,根据表中唯一的列(或列组合)为表指定一个“自然”主键
。或者创建一个代理 AUTO_INCRMENT
键。然后创建您可能需要的任何其他键来查找和/或JOINing
。
是的,索引使查询运行得更快。当您获得一些包含数百万行的表时,我们可以讨论除此之外的微妙问题。
在不使用任何索引的SELECT
中,将扫描整个表(“表扫描”)。这很“慢”,尤其是当表“很大”时。不过没关系。
如果可以使用索引,则查找单行(“点查询”)会很快。如果可以使用PRIMARY KEY
,速度会更快,但我们讨论的是典型情况下的 1 毫秒与 2 毫秒。即使对于 十亿 行表,我们讨论的是 10 毫秒与 20 毫秒。另一方面,十亿行的表扫描可能需要几个小时。这是索引为何如此重要的一个极端例子。
在您的查询中,您会想要
INDEX(ucity)
如果您按原样提供查询和表的 EXPLAIN SELECT ...
,然后添加该索引并再次运行 EXPLAIN
,您将看到差异。我们可以讨论事情如何变得更好以及表扫描如何消失。
查看我的cookbook有关如何编写最佳索引的更多讨论。
另一个提示:不要将 DATE
和 TIME
分成两个单独的字段。在需要时拆分 DATETIME
比将两个字段放在一起要容易得多。
关于mysql - 使用索引优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36958647/