MySQL字符串类型和数字类型索引的效率

2023-02-15 14:49:35 浏览数 (1)

  1. From:

mysql分别用数字INT和中文varchar做索引查询效率上差多少

性能相当

mysql中区别性能的是采用哪种索引方式,而不是索引的数据类型。

MySQL的btree索引和hash索引的区别

  1. hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,
  2. btree(B-Tree)索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,
  3. 综上,hash 索引的查询效率要远高于 btree(B-Tree) 索引。 虽然 hash 索引效率高,但是 hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。

(1)hash 索引仅仅能满足=,<=>,IN,IS NULL或者IS NOT NULL查询,不能使用范围查询。

代码语言:javascript复制
     由于 hash 索引比较的是进行 hash 运算之后的 hash 值,所以它只能用于等值的过滤,
     不能用于基于范围的过滤,因为经过相应的 hash 算法处理之后的 hash 值的大小关系,
     并不能保证和hash运算前完全一样。

(2)hash 索引无法被用来避免数据的排序操作。

代码语言:javascript复制
     由于 hash 索引中存放的是经过 hash 计算之后的 hash 值,
     而且hash值的大小关系并不一定和 hash 运算前的键值完全一样,
     所以数据库无法利用索引的数据来避免任何排序运算;
  1. From

对比MySQL中int、char以及varchar的性能

我最近针对int、long、char、varchar进行了一次性能测试,发现它们其实并没有太大的性能差距:

备注:

代码语言:javascript复制
c8=char(8), s8=varchar(8), i8=(bigint), c4=char(4), s4=varchar(4), i4=char(4)

100w行无索引情况下查询:

代码语言:javascript复制
执行[c8查询]20次, 平均耗时312.0ms 
执行[s8查询]20次, 平均耗时334.3ms 
执行[i8查询]20次, 平均耗时276.95ms 
执行[c4查询]20次, 平均耗时354.95ms 
执行[s4查询]20次, 平均耗时340.45ms 
执行[i4查询]20次, 平均耗时291.1ms

创建索引:

代码语言:javascript复制
c8索引耗时2439ms 
s8索引耗时2442ms 
i8索引耗时1645ms 
c4索引耗时2296ms 
s4索引耗时2303ms 
i4索引耗时1403ms

有索引情况下查询:

代码语言:javascript复制
执行[c8查询]10000次, 平均耗时0.271ms 
执行[s8查询]10000次, 平均耗时0.2354ms 
执行[i8查询]10000次, 平均耗时0.2189ms 
执行[c4查询]10000次, 平均耗时0.303ms 
执行[s4查询]10000次, 平均耗时0.3094ms 
执行[i4查询]10000次, 平均耗时0.25ms

结论: 无索引:全表扫描不会因为数据较小就变快,而是整体速度相同,int/bigint作为原生类型稍快12%。 有索引:char与varchar性能差不多,int速度稍快18%

在数据存储、读写方面,整数与等长字符串相同,varchar额外多了一个字节所以性能可能会些许影响(1/n)。 在数据运算、对比方面,整数得益于原生支持,因此会比字符串稍快一丁点。 若采用索引,所谓整数、字符串的性能差距更是微乎其微。

在实际开发中,许多开发者经常使用char(1)、char(4)这样的字符串表示类型枚举,这种做法在我看来属于最佳方案,因为这种做法在存储空间、运算性能、可读性、可维护性、可扩展性方面,远胜于int、enum这种数据类型。

在不使用比较和范围查询的时候,例如我们数据的每一个行索引,userid这样的字段就只需要hash索引,那么我们就可以将它定义为HASH

代码语言:javascript复制
ALTER TABLE user_account ADD INDEX userid ( userid ) USING HASH;

不过这里仍然还有一些需要注意的部分

警惕 InnoDB 和 MyISAM 创建 Hash 索引陷阱

MySql 最常用存储引擎 InnoDB 和 MyISAM 都不支持 Hash 索引,它们默认的索引都是 B-Tree。但是如果你在创建索引的时候定义其类型为 Hash,MySql 并不会报错,而且你通过 SHOW CREATE TABLE 查看该索引也是 Hash,只不过该索引实际上还是 B-Tree。 虽然常见存储引擎并不支持 Hash 索引,但 InnoDB 有另一种实现方法:自适应哈希索引。InnoDB 存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引。

0 人点赞