我需要为我的表(列)添加索引,无意中发现了以下帖子:

How many database indexes is too many?

引述:

如果只有两个不同的值,索引真的毫无意义吗?给出如下表(MySQL数据库,InnoDB)

Id (BIGINT)
fullname (VARCHAR)
address (VARCHAR)
status (VARCHAR)

其他条件:

  • 该数据库包含3亿条记录
  • 状态只能是"启用"和"禁用"
  • 1.5亿条记录的状态=已启用,1.5亿条记录的状态为

我的理解是,如果没有状态索引,一个where status=’enabled’的select将导致一个完整的表扫描,需要处理3亿条记录?

当我对状态使用BTREE索引时,查找的效率有多高?

我该不该给这个专栏编索引?

MySQL InnoDB提供了哪些替代方法(可能是任何其他索引),可以通过给定示例中的"where status="enabled"子句高效地查找记录,并且值的基数/ Select 性非常低?

推荐答案

你描述的索引几乎毫无意义.当需要 Select small行(与总行数相比)时,最好使用索引.

其原因与数据库访问表的方式有关.表格可以通过一次完整的表格扫描来判断,每个块依次被读取和处理.或者通过rowid或key lookup,其中数据库有一个key/rowid并读取它所需的确切行.

如果使用基于主键的where子句或另一个唯一索引(例如where id = 1),数据库可以使用该索引获得对行数据存储位置的精确引用.这显然比进行全表扫描并处理每个块更有效.

现在回到您的示例,您有一个where子句where status = 'enabled',索引将返回150m行,数据库将不得不使用单独的小读取来依次读取每一行.而通过全表扫描访问表,则允许数据库使用更高效的更大读取.

在某一点上,最好只进行一次完整的表扫描,而不是使用索引.使用mysql,您可以在查询中使用FORCE INDEX (idx_name),以便在每个表访问方法之间进行比较.

参考:

Mysql相关问答推荐

如何有效地计算共同的朋友/追随者?

MySQL InnoDB:可以在没有回滚损失的情况下从运行的查询中进行大型插入吗

使用MySQL工作台导出具有数据的数据库表并导入到其字段具有不同数据类型的同一表中

亚马逊RDS MySQL-无法';t执行';使用读取锁定刷新表';

警告:MYSQL_OPT_RECONNECT 已弃用

是否可以使用以EXPLAIN EXTENDED ...开头的 SQL 语句修改数据?

如何在 mysql 中获取 Day Wise 的平均值?

使用 DISTINCT 时无法从数据库中查询所有数据

如何解决这个特定的 SQL 查询?我的解决方案还返回不想要的值

根据使用 mysql 的第一个过滤结果添加更多表行

如何使用 SQL 聚合和求和相似 Select 的值?

如何判断嵌套查询返回的元组中的每个条目是否相同?

通过 Gorm 查询模型

使用 MySQL LIMIT、OFFSET 进行分页

如何查看打开了多少 MySQL 连接?

MySQL - 基于同一表中的行求和列值

MySQL where NOT IN 名称数组?

启用 NO_BACKSLASH_ESCAPES 选项时如何转义文字百分号?

在 MySQL 中签名或未签名

在 Postgresql 中模拟 MySQL 的 ORDER BY FIELD()