栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

尽管覆盖索引,MySQL MyISAM慢count()查询

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

尽管覆盖索引,MySQL MyISAM慢count()查询

这是怎么回事。

The SELECT COUNT (...) icd_index where icd='25000'

将使用索引,该索引是与数据分开的BTree。但是它以这种方式扫描:

  1. 查找具有icd =‘25000’的第一个条目。这几乎是瞬时的。
  2. 向前扫描,直到找到icd的变化。这将仅扫描索引,而不接触数据。根据EXPLAIN,将有大约910,104个索引条目要扫描。

现在,让我们看一下该索引的BTree。根据索引中的字段,每行将恰好是22个字节,加上一些开销(估计为40%)。MyISAM索引块为1KB(参见InnoDB的16KB)。我估计每个块有33行。910,104
/
33说,要读取COUNT,需要读取大约27K块。(注意

COUNT(core_id)
需要检查是否
core_id
为空,
COUNT(*)
不是这样;这是一个很小的差异。)在普通硬盘驱动器上读取27K块大约需要270秒。您很幸运能在60秒内完成。

第二次运行在key_buffer中找到了所有这些块(假设key_buffer_size至少为27MB),因此它不必等待磁盘。因此,它要快得多。(这将忽略查询缓存,您可以明智地刷新或使用SQL_NO_CACHE。)

5.6恰好无关紧要(但是感谢您提及它),因为此过程自4.0或更低版本以来没有更改(除了utf8不存在;更多内容请参见下文)。

切换到InnoDB可以通过两种方式提供帮助。主键将与数据“聚集”在一起,而不是存储为单独的BTree。因此,一旦数据或PK被缓存,另一个立即可用。块的数量将更像是5K,但它们将是16KB块。如果高速缓存很冷,这些文件可能会更快地加载。

您问“我是否需要一个单独的icd索引?”-那么这会使MyISAM
BTree的大小缩小到每行约21个字节,因此BTree的大小约为21/27倍,没有太大的改进(至少对于冷缓存情况)。

另一个想法是, 如果

icd
始终是数字且始终是数字,则使用
MEDIUMINTUNSIGNED
ZEROFILL
如果它可以有前导零,则继续使用。

糟糕,我没注意到字符集。(我已经固定了上面的数字,但让我详细说明。)

  • CHAR(5)允许5个 字符
  • ascii每个 字符 占用1 个字节 。 __
  • utf8每个 字符 最多占用3 个字节 。 __
  • 因此,CHAR(5)CHARACTER SET utf8 始终 占用15 个字节 。 __

将列更改为

CHAr(5) CHARACTER SET ascii
会将其缩小到5个字节。

将其更改为MEDIUMINT UNSIGNED ZEROFILL会将其缩小为3个字节。

缩小数据将使I / O速度大致成比例(在另外两个字段中再允许6个字节之后)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/398500.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号