mysql - 为什么 Index 只在强制使用时使用,默认不使用?

标签 mysql indexing myisam

我的表中有大约 4.2 亿条记录。 user_tablecolC 列只有一个索引。下面的查询返回大约 150 万条记录,基于 colC。但是不知何故没有使用索引并在 20 到 25 分钟内返回记录

select colA ,ColB , count(*) as count 
from user_table 
where colC >='2019-09-01 00:00:00' 
      and colC<'2019-09-30 23:59:59' 
      and colA in ("some static value") 
      and ColB in (17) 
group by colA ,ColB;

但是当我执行强制索引时,它开始被使用并仅在 2 分钟内返回记录。我的问题为什么MYSQL在获取时默认不使用索引 索引的时间要少得多?我已经重新创建了索引并进行了修复,但默认情况下无法使用它。

另一个信息观察是相同的查询(没有强制索引)适用于前几个月(具有相同的数据量)。

更新 Evert询问的细节

创建表 USER_TABLE ( id bigint(20) 无符号 NOT NULL AUTO_INCREMENT, COLA varchar(10) 默认为空, COLB int(11) 默认为空, COLC 日期时间默认为空, .... 主键(id), KEYcolA(COLA), KEYcolB(COLB), KEYcolC(COLC) ) ENGINE=MyISAM AUTO_INCREMENT=2328036072 DEFAULT CHARSET=latin1 |

最佳答案

为了获得更好的性能,您可以尝试使用复合索引 .. 基于 where 子句中涉及的列
并尝试更改内部连接中的 IN 子句
假设您的 IN 子句内容是一组固定值,您可以使用联合(或具有所需值的新表)

例如使用联合(如果 IN 子句是子查询,你可以做类似的事情)

select user_table.colA ,ColB , count(*) as count 
from user_table 
INNER JOIN  ( 
  select 'FIXED1' colA
  union
  select 'FIXED2'
  ....
  union 
  select 'FIXEDX'
  )  t on t.colA = user_table.colA  
where colC >='2019-09-01 00:00:00' 
      and ColB = 17  
group by colA ,ColB;

您还可以在表 user_table 的列上添加复合索引

   colA, colB, colC

对于与 mysql 查询优化器使用的元素相关的元素,用于决定在几个方面使用索引,并且查询优化器为所有这些分配成本
任何你应该考虑的事情

  • Where子句涉及的列
  • 表的大小(通常情况下不是连接中表的大小)
  • 估计将获取多少行(以决定是使用索引还是简单地扫描表)
  • 如果数据类型在 jion 和 where 子句中的列之间匹配或不匹配
  • 函数或数据类型转换的使用,包括排序规则的错误
  • 索引的大小
  • 索引的基数

所有这些选项都被评估为成本,这导致索引选择

在你的情况下,作为日期的 colC 可能意味着数据转换(将文字值视为字符串)并且为此未选择索引..

也是为了这个,我建议了一个复合索引,其中最左边的列与非转换值相关

关于mysql - 为什么 Index 只在强制使用时使用,默认不使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58551537/

相关文章:

php提交仅给出填充表单的数组中的最后一个值

indexing - OrientDB 中的二级索引

mysql - varchar(25) 引用字段最有效的索引类型是什么?

mysql - "Table is marked as crashed"- 由检查表修复...?

mysql - 带计算的自引用 SQL 查询

PHP/MySQL 文本字段按条件搜索

mysql - 我可以通过将表转换为 MyISam 来减小 ibdata1 文件的大小吗?

6GB RAM 的 mysql my.cnf 配置

mysql - 想要保持MySQL中两个表之间的关系

java - 使用 Java 的非阻塞多线程 MySQL