MySQL索引的分类、何时使用、何时不使用、何时失效?

说白了,MySQL索引是加快查询速度的“高速公路”,但如果使用不当,也可能成为“堵车”。

为了扩展, 普通索引是最基本的。
去年我们跑的3 000级电商项目中,使用普通索引的单表查询速度比全表扫描至少快5 0%。
唯一索引适用于数据校验,比如订单号,必须唯一,但要注意不允许重复值。
主键索引是系统自动创建的。
只需使用自增ID即可。
不要手动创建,这是浪费资源。
组合索引时,要特别注意最左边的前缀,例如索引(a,b,c)。
查询条件必须从a开始。
上次我们遇到的坑是WHERE b = X找不到数据,因为索引只使用了b之后的部分。
不要与全文索引混淆。
它只支持char/varchar/text,并且查询必须与之匹配。
像 LIKE '%keyword' 这样的传统模糊查询将不起作用。

一开始我以为索引越多越好,但后来发现是错误的。
如果表的记录很少(例如少于2 00条),则不需要建立索引,数据库会更快地扫描整个表。
还有另一个关键细节。
例如,性别字段只有两个值:男性和女性。
建立索引是没有用的。
如果使用 EXPLAIN 看到类型是 ALL,就将其删除即可。
去年有一个项目,数据量3 000条,但是用户名字段都是中文。
LIKE '%张%' 根本无法索引,所以最后改为前缀匹配。

提醒: 不要对索引列进行类型转换,例如WHEREage = '2 5 ',因为字符串和整数比较将直接失败。
另外,对于更新频繁(例如每日增量超过1 000)的表,索引维护成本非常高,必须权衡索引带来的查询收益。

最后提一个建议: EXPLAIN 并不是万能药。
它只能告诉你MySQL“想要”怎么走,但实际执行取决于数据分布。
我建议每周花半个小时观察在线SQL的关键字段,看看是否存在“有索引但没有删除”的情况。

MySQL索引失效的7种情况及使用建议

索引失败之类的情况有好几种……说实话,陷阱还蛮多的。

1 .未在 or 条件中建立索引的列 例如,表user有user_id(不带索引)和name(带索引),可以检查user_id=1 或name='John' 此时,该名称就无效被索引了。
因为OR连接,MySQL觉得非索引列无法建立索引,所以干脆不使用索引。
有何建议?要么索引user_id,不要用or,不然对索引伤害很大。

2 复合索引不使用最左边的前缀 例如,对于复合索引(first_name,last_name),可以直接检查last_name='Smith' 该索引是无用的,因为 MySQL 认为您甚至没有使用最左边的名字。
建议搜索时带上名字,即使是'%',如'%%',这样仍然可以使用最左边的索引。

3 比如以%开头的查询 如果你检查LIKE名字'%John',索引肯定是无效的。
因为MySQL必须扫描整个表才能找到包含John的表。
有何建议?不要以 % 开头、使用全文索引或将数据存储在搜索引擎中。

4 条件数据类型不匹配 例如,如果索引是字符串类型,并且您检查name=1 2 3 ,MySQL将自动更改类型。
如果类型改变,索引就会消失。
建议检查时匹配类型,如name='1 2 3 ',不要让它自行改变。

5 对 where 子句中的索引列进行算术运算 例如,如果指定age+1 =2 5 ,则索引将立即被销毁。
因为MySQL必须先计算age+1 ,然后再检查。
建议更改等式两边并检查age = 2 4 ,以便该指标仍然可以使用。

6 使用 where 函数子句 例如,如果指定 UPPER(name)='JOHN',则索引将无用。
因为MySQL必须先将其转换为大写,然后再进行检查。
有何建议?要么存储函数的结果并创建单独的索引,要么不在任何地方使用该函数。

7 MySQL感觉全表扫描更快 例如,如果一个表只包含几百条数据,MySQL 认为扫描表比使用索引更容易,因此建立索引将毫无意义。
有何建议?小表上的索引不是很重要,但是大表就应该建立。

使用索引时要注意以下几点: 1 . 建立性别指数效果不佳,性别具有唯一性虚弱的。
2 、不要在频繁更新的字段上创建索引,例如订单状态。
3 、索引列必须出现在“WHERE”子句中,否则索引就白建了。
4 .不要在索引列上使用!=,因为MySQL无法找到索引。

事实上,创建索引是一个技术活,取决于具体的业务场景,不能一概而论。