mysql MyISAM 和 InnoDB 索引使用差异

2023-11-23

我有这些小桌子,item and category:

CREATE TABLE `item` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(150) NOT NULL,
  `category_id` mediumint(8) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`),
  KEY `category_id` (`category_id`)
) CHARSET=utf8

CREATE TABLE `category` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(150) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `name` (`name`)
) CHARSET=utf8

我插入了 100 个类别和 1000 个项目。

如果我运行这个:

EXPLAIN SELECT item.id,category.name AS category_name FROM item JOIN category ON item.category_id=category.id;

然后,如果表的引擎是 InnoDB 我得到:

+----+-------------+----------+-------+---------------+-------------+---------+--------------------+------+-------------+
| id | select_type | table    | type  | possible_keys | key         | key_len | ref                | rows | Extra       |
+----+-------------+----------+-------+---------------+-------------+---------+--------------------+------+-------------+
|  1 | SIMPLE      | category | index | PRIMARY       | name        | 452     | NULL               |  103 | Using index |
|  1 | SIMPLE      | item     | ref   | category_id   | category_id | 3       | dbname.category.id |    5 | Using index |
+----+-------------+----------+-------+---------------+-------------+---------+--------------------+------+-------------+

然而,如果我切换到 MyISAM(使用alter table engine=myisam) I get:

+----+-------------+----------+--------+---------------+---------+---------+-------------------------+------+-------+
| id | select_type | table    | type   | possible_keys | key     | key_len | ref                     | rows | Extra |
+----+-------------+----------+--------+---------------+---------+---------+-------------------------+------+-------+
|  1 | SIMPLE      | item     | ALL    | category_id   | NULL    | NULL    | NULL                    | 1003 |       |
|  1 | SIMPLE      | category | eq_ref | PRIMARY       | PRIMARY | 3       | dbname.item.category_id |    1 |       |
+----+-------------+----------+--------+---------------+---------+---------+-------------------------+------+-------+

我的问题是,为什么处理索引的方式存在这种差异?


在InnoDB中,任何二级索引内部都包含表的主键列。所以索引nameon column (name) 隐式地位于 columns (name, id) 上。

这意味着 EXPLAIN 将您对类别表的访问显示为“索引扫描”(这显示在type列作为“索引”)。通过扫描索引,它还可以访问 id 列,它使用该列来查找第二个表 item 中的行。

然后,它还利用 (category_id) 上的项目索引(实际上是 (category_id, id)),并且只需读取索引即可为您的选择列表获取 item.id。根本不需要阅读表格(这显示在Extra列为“使用索引”)。

MyISAM 不会以这种方式存储主键和辅助键,因此它无法获得相同的优化。对类别表的访问是“ALL”类型,这意味着表扫描。

我希望对 MyISAM 表项的访问是“ref”,因为它使用 (category_id) 上的索引查找行。但是,如果表中的行很少,或者没有完成,优化器可能会得到不正确的结果ANALYZE TABLE item自创建索引以来。


回复您的更新:

看起来优化器更喜欢索引扫描而不是表扫描,因此它抓住机会在 InnoDB 中进行索引扫描,并将类别表放在第一位。优化器决定对表重新排序,而不是按照您在查询中指定的顺序使用表。

在 MyISAM 表中,无论它选择先访问哪个表,都会进行一次表扫描,但通过将类别表放在第二位,它会连接到类别的主键索引而不是项目的辅助索引。优化器更喜欢查找而不是唯一键或主键(类型“eq_ref”)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql MyISAM 和 InnoDB 索引使用差异 的相关文章

  • mysql 准备好的语句错误:MySQLSyntaxErrorException

    我使用准备好的语句编写了选择语句 每次尝试运行都会出现此错误 我如何克服这个错误 我的jdbc连接器是mysql connector java 5 1 13 bin jar 我的代码 public Main add ad to getAdD
  • 在 Bluemix 中激活 PHP 扩展

    这纯粹是 Bluemix 问题 我的代码在本地主机上顺利运行 但是当我将其迁移到 Bluemix 时 我的数据库连接失败了 检查日志 我发现问题 调用未定义的函数 mysqli init HTTP 响应 500 我发现扩展已被禁用以使其更小
  • InnoDB如何存储字符列?

    这个问题仅解决 短 的问题CHAR and VARCHAR列存储在 InnoDB 表中 Does a CHAR 10 列正好占用 10 个字节吗 尾随空格会发生什么情况 对于每个字符需要超过 1 个字节的字符集怎么办 如何VARCHAR 1
  • 我无法访问 XAMPP phpMyAdmin;它说:错误 MySQL 说:文档无法连接:无效设置

    完整错误消息 Error MySQL said Documentation Cannot connect invalid settings Connection for controluser as defined in your conf
  • 存储 MySQL GUID/UUID

    这是我能想到的将 UUID 生成的 MySQL GUID UUID 转换为二进制文件 16 的最佳方法 UNHEX REPLACE UUID 然后将其存储在 BINARY 16 中 我应该知道这样做有什么影响吗 从 MySQL 8 0 及以
  • 创建表时 MySQL 语法错误

    我正在尝试在 Filemaker gt MySQL 转换脚本中使用此查询 表创建步骤直接从 phpMyAdmin 导出中获取 并添加到 DROP 语句中 DROP TABLE IF EXISTS artifacts CREATE TABLE
  • 空间索引无助于 SQL 查询(性能非常慢)

    我正在尝试测试包含 170 万个邮政编码的表中纬度 经度值的空间索引的性能 我创建了一个地理列并向其中添加了一个索引 但是使用空间索引的查询比在同一个表中的纬度 经度列上使用 正常 索引的查询要慢得多 至少 100 倍 但是查询计划显示索引
  • Visual Studio 2015:SQL 数据源:无法检索架构。确保 ConnectionString 和 SelectCommand 属性有效

    我有以下ASP Net网页的开发环境 VS 2015专业版 使用 Net Framework 4 0 MySQL服务器5 6 MySQL Net 连接器 6 9 5 MySQL for Visual Studio 2 0 2 我能够从 Vi
  • 交叉表的动态 MySQL 查询/视图

    我目前有一个带有以下 sql 的硬编码视图 select username case user role role id when 1 then true else false end as ROLE SUPER case user rol
  • 如何在我的查询中使用日期格式?

    这适用于 phpmyadmin 但是当我在代码上使用时给我一个错误 错误说 解析错误 语法错误 意外的 我的语法有什么问题 gt
  • 复制具有不同列名的 MySQL 表

    我需要将 table1 中与特定列匹配的所有行复制到具有不同列名称的 table2 中 例如 table1 name oldAddressBook table1 的列 name Name Surname Number table2 name
  • 如何在每次运行 python 程序时添加新列

    我希望我的表的第一列作为卷号 第二列作为名称 每当我运行 python 程序时 我想在表中添加一列日期 在这个新列中 我想填充从 user list 获得的列表将包含值 P A P P 等 如何处理 我尝试首先通过 alter 命令添加一列
  • MySQL Workbench:如何将 mysql 数据库导出到 .sql 文件?

    我需要将 mysql 工作台中的数据库导出到文件 sql 该怎么办 在 MySql Workbench 版本 8 0 中 您只需按照以下步骤操作即可 Go to Server tab Go to 数据库导出 这会打开类似这样的东西 在中选择
  • Codeigniter,为MySQL创建表和用户

    我想以编程方式使用 CI 创建数据库和用户 到目前为止 我有这 2 个简单的 MySQL 语句 CREATE DATABASE testdb DEFAULT CHARACTER SET utf8 COLLATE utf8 general c
  • MySQL 查询性能有帮助,许多相同的表被连接

    我正在编写一个创建 SQL 查询的 PHP 脚本 该脚本和数据库用于 Joomla CMS 特别是它查询 SOBIPro 组件的表 以使用在此组件中输入的数据 然而 由于 SOBI Pro 表的处理方式 字段的每个实例都是表中自己的行 这意
  • 将 3d NumPy 数组重塑为 2d NumPy 数组时遇到问题

    我正在研究图像处理问题 我的数据以 3 维 NumPy 数组的形式呈现 其中 x y z 条目是图像 z 的 x y 像素 数值强度值 有 100000 张图像 每张图像为 25x25 因此 数据矩阵的大小为 25x25x10000 我试图
  • 无法使用 Node.JS 将 null 值发送到 MySQL 数据库

    我正在尝试发送null使用 Node JS 到我的 MySQL 数据库 con query INSERT INTO Routes routeTrigger VALUES null title test function err result
  • 选择 MYSQL 行,但将行转换为列,将列转换为行

    我想选择数据库中的所有行 但我希望它们按相反的顺序排列 意思是 我想使用第一列数据作为新实体 并将实体作为第一列 我想你明白我的意思 这是一个例子 id name marks 1 Ram 45 2 Shyam 87 to id 1 2 Na
  • 更改 MySQL 中的列名称 [重复]

    这个问题在这里已经有答案了 搜索后我不知道我需要在 ALTER TABLE 中做什么genres更改列id to genre id有任何想法吗 alter table genres change id genre id int 10 aut
  • 将 1 添加到字段

    如何将以下 2 个查询变成 1 个查询 sql SELECT level FROM skills WHERE id id LIMIT 1 result db gt sql query sql level int db gt sql fetc

随机推荐

  • 如何在 Delphi XE3 中的 Firemonkey FM2 应用程序中设置非客户区的样式

    我之前在 Delphi XE2 时间范围内问过这个问题 当时的答案很漂亮丑陋的黑客 根据官方发行说明 现在 Delphi XE3 支持非客户端主题 在Firemonkey FM2中的Delphi XE3中如何做到这一点 我相信这一定与样式书
  • Jenkinsfile - 脚本管道语法中的条件阶段执行

    我们正在使用脚本管道我们的语法Jenkinsfile其中定义了很多阶段来构建和部署我们的代码 我们有一个用例 如果我正在做一个任务 我想运行我的所有阶段完整构建但如果我需要执行一些 AWS 路由 则仅运行一个特定阶段 我知道我可以使用if
  • 如果将 PendingIntent 上的标志设置为 0 会发生什么?

    当您将待处理意图的标志设置为 0 时 到底会发生什么 它只是不升起一个标志还是默认为其他标志之一 不 这是创建新 PendingIntent 的 默认 行为 无论该行为是否已存在 如果您想要更专门的行为 例如在底层 Intent 相同的情况
  • TinyTds 错误:Adaptive Server 连接超时

    我们正在 Rails 3 2 12 ruby 1 9 3 上使用当前的tinyTDS gem 0 6 2 运行 Ruby on Rails 应用程序 我们使用 MS SQL 2012 或 2014 并面临比平常更多的以下错误消息 TinyT
  • 如何将 16 位 PCM 音频字节数组转换为双精度或浮点数组?

    我正在尝试对 3gpp 音频文件执行快速傅里叶变换 该文件包含来自手机麦克风的 44100kHz 的 5 秒小录音 出于显而易见的原因 我能找到的每个 Java FFT 算法都只接受 double float 或 Complex 输入 但我
  • 将 Azure 磁盘附加到 AKS pod 时出现权限错误

    我已经与这个错误作斗争了几个小时了 找到了几篇文章 但到目前为止没有任何帮助 我的工作基于 操作指南 gt 配置数据卷 gt Azure 磁盘 静态 https learn microsoft com en us azure aks azu
  • C++ 中的变量到底是什么?

    标准说 A variable通过对象的声明引入 变量的名称表示对象 但这个定义实际上意味着什么 变量是否为对象提供名称 即变量是否只是匿名对象的命名机制 或者变量就是名称本身 或者变量是否是一个命名对象 因为每个变量也是一个对象 或者变量只
  • 为什么 check_box 表单助手会生成两个复选框,其中一个是隐藏的?

    这段代码 form fo store products 做 f f check box track inventory 创建这个 html
  • 如何通过 jQuery 设置光标图像?

    在网络应用程序中 我有一个加载事件 如果浏览器正在从服务器加载数据 我希望光标更改为显示时钟的 gif 如何更改光标外观 我只在参考光标外观的博客中找到了这个 this css cursor move 我想改为加载图像 试试这个方法 thi
  • 子集合 List.Any 的表达式树

    我正在使用表达式树构建通用 linq 查询 在子集合上创建表达式时我陷入困境 由于类型不兼容 方法调用会崩溃 通常我知道该放什么 但是 Any 方法调用让我感到困惑 我已经尝试了所有我能想到的类型 但没有成功 任何帮助 将不胜感激 这是我的
  • FullCalendar 在 dayClick 上打开引导模式

    我想在用户单击 fullCalendar 中的某一天时打开引导模式 我查看了 dayClick 事件 但不知道如何调用模型 dayClick function date jsEvent view call the model 调用引导模型的
  • 我必须使用什么 Uxtheme 函数来获取最小化、最大化和关闭按钮的默认大小?

    我正在使用DrawThemeBackground函数在画布上绘制一些系统元素 我需要绘制表单的标题按钮 我错过的唯一部分是如何获得default标题按钮的大小 Exist any Uxtheme function to get that i
  • Android:将多行插入sqlite数据库不起作用

    我正在使用以下 Android 项目方法将单行插入数据库 myDB execSQL INSERT INTO Buss BussName RouteName VALUES buss1 buss2 效果很好 我看到这个链接在sqlite数据库中
  • 这个素数生成器的执行时间可以提高吗?

    我撰写本文时的最初目标是尽可能留下最小的足迹 我可以自信地说 这个目标已经实现了 不幸的是 这使我的实施速度相当缓慢 要生成 200 万以下的所有素数 在 3Ghz Intel 芯片上大约需要 8 秒 是否有办法以最小的牺牲来改善此代码的执
  • Google 图表显示错误的月份

    I ve got a google line chart which shows the correct line but the annotation of the Date is off by one month exactly The
  • 什么时候应该避免使用 NHibernate 的延迟加载功能?

    我听到的关于 NHibernate 延迟加载的大部分说法是 使用它比不使用它要好 似乎最小化数据库访问以减少瓶颈是有意义的 但几乎没有什么事情是不需要权衡的 当然它会迫使你有一些限制设计virtual特性 但我也注意到一些开发人员关闭了某些
  • PostgreSQL 多维数组

    我试图将数据作为多维数组传递 但我得到的行为对我来说似乎很奇怪 具体来说 我试图从二维数组中获取单个元素 因此从二维数组中获取一维数组 但它没有按照我期望的方式工作 在下面的示例中 2 4 和 5 按我预期的方式工作 但 1 和 3 则不然
  • 如何在Python中使用日志记录打印列表项+整数/字符串

    我想打印带有项目索引的列表项目 例如 0 idx 10 degree 0 1 idx 20 degree 0 根据下面的代码 如何将 0 附加为整数 字符串 列表项 import logging class Node object slot
  • 一般最小值和最大值 - C++

    编写一个通用的最小函数 我想到了两个问题 该代码适用于任何输入类型和不同的参数编号 namespace xyz template
  • mysql MyISAM 和 InnoDB 索引使用差异

    我有这些小桌子 item and category CREATE TABLE item id mediumint 8 unsigned NOT NULL AUTO INCREMENT name varchar 150 NOT NULL ca