mysql - 使用索引优化查询

标签 mysql database query-optimization

我对这个还是很困惑。这是来自在线问题集。

假设我有表 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'
  1. 我可能对这个定义有一些误解。但最多只允许创建两个索引结构,有序索引和B+树索引该如何选择?

  2. 对于 checkin 表,我们应该创建两个索引(uid、pid)吗?如果是的话,作为主索引还是辅助索引有什么区别吗?

我在这里复制了原始问题

“假设对于每个查询,您最多可以创建两个索引结构以使查询更快,您将创建什么索引结构,以及这将如何改变评估计划和运行时间(换句话说,获取单个记录具有使用这些索引的特定非键值)。”

最佳答案

“没有人”使用NATURAL JOIN。请更改为 JOIN ... ON ... 语法,以便您明确了解表之间的关联方式。另外,请为每个表提供SHOW CREATE TABLE

“只有2个索引结构”?你是在哪里拿到的? InnoDB“需要”一个主键最多64个“辅助键”。 PRIMARY KEY 与数据一起存储并以这种方式对数据进行排序。辅助键中包含主键,因此它们会进行第二次查找以获取数据。主键和辅助键都是 BTree 结构。

根据 MySQL 的定义,PRIMARY KEYUNIQUE 和一个索引。因此,根据表中唯一的列(或列组合)为表指定一个“自然”主键。或者创建一个代理 AUTO_INCRMENT 键。然后创建您可能需要的任何其他键来查找和/或JOINing

是的,索引使查询运行得更快。当您获得一些包含数百万行的表时,我们可以讨论除此之外的微妙问题。

在不使用任何索引的SELECT中,将扫描整个表(“表扫描”)。这很“慢”,尤其是当表“很大”时。不过没关系。

如果可以使用索引,则查找单行(“点查询”)会很快。如果可以使用PRIMARY KEY,速度会更快,但我们讨论的是典型情况下的 1 毫秒与 2 毫秒。即使对于 十亿 行表,我们讨论的是 10 毫秒与 20 毫秒。另一方面,十亿行的表扫描可能需要几个小时。这是索引为何如此重要的一个极端例子。

在您的查询中,您会想要

INDEX(ucity)

如果您按原样提供查询和表的 EXPLAIN SELECT ...,然后添加该索引并再次运行 EXPLAIN,您将看到差异。我们可以讨论事情如何变得更好以及表扫描如何消失。

查看我的cookbook有关如何编写最佳索引的更多讨论。

另一个提示:不要将 DATETIME 分成两个单独的字段。在需要时拆分 DATETIME 比将两个字段放在一起要容易得多。

关于mysql - 使用索引优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36958647/

相关文章:

database - 何时分隔数据库列含义(通用列)

sql-server - 加入非PK字段,varchar数据类型的长度是否决定查询速度? SQL Server 2008

mysql修复使用哪里;

sql - 带 Left Join 的 Mysql 查询太慢了

php - Codeigniter activerecord 选择 null 到虚拟列中

php - 通知: unserialize(): Error at offset | data trimmed in MySQL

php - 在 php 中编辑复选框数据并在 mysql 中更新行

mysql - 无法启动mysql服务器

mysql - 多种类型用户的数据库

sql-server - 适合在排名函数中排序的索引