避免锁表:为Update语句中的Where条件添加索引字段

不幸的是,几年前我们公司的系统确实很混乱。
我记得当时我们团队负责的业务系统的数据录入速度慢得像蜗牛。
当时我以为服务器出问题了。
进一步调查发现,工单是在等待其他业务更新,实际上是有欺骗性的。

当时,我们每天要处理数千条数据。
结果一更新,整个表就卡住了。
后来深入分析发现原因是update操作中的SQL语句。
条件中的字段未建立索引。
结果,其他事务在访问该表时必须等待更新完成。
难道这行不通吗?
我在本地环境中复制了它,发现修改和添加新接口的顺序完全是相互控制的。
有时更新操作需要等待半天。
经过进一步分析,我发现MySQL修改数据时,如果条件后面的字段没有索引或者索引没有命中,很容易锁表。
一旦出现这个锁表,其他事务访问这个表就成为问题,系统响应速度会直接变慢。

然后我们使用命令行检查,发现列表中有很多锁定或活动的表。
这时我们才知道问题的严重性。
然后我们总结一下我们的经验。
在写Update语句时,一定要注意where条件中的字段是否有索引。

为了优化查询效率并避免锁定整个表,使用索引来提高性能非常重要。
然后我们适当地设计了索引,以确保Update语句中的条件包含索引字段。
这样,数据库的性能和并发性都得到了提升。
这次事件让我敏锐地意识到索引在数据库操作中的重要性再清楚不过了。

加索引过程中锁表会select不了吗

添加索引将锁定表并阻止选择。
MySQL5 .5 及更早版本:ALTERTABLE ADDINDEX锁定整个表。
MySQL5 .6 及更高版本:InnoDB默认为在线DDL,允许SELECT。
特殊情况:MDL锁冲突会被阻塞。
不要这样做:检查事务隔离级别。

mysql怎么删除索引 mysql创建和删除索引的完整指南

删除索引其实很简单。
使用DROP INDEX,例如DROP INDEX idx_username ON users;这样就可以了。
但说实话,我更喜欢使用 ALTER TABLE users DROP INDEX idx_username;,这样语义更清晰,一眼就能看出你正在删除表上的索引。
我以前做过一次,第一次差点就出错了,但是后来我改了,就好多了。

创建索引的方法有多种。
普通索引,最简单,CREATE INDEX idx_email ONcustomers(email);或 ALTER TABLE 客户 ADD INDEX idx_email(电子邮件);会起作用的。
唯一索引等于,CREATE UNIQUE INDEX udx_order_no ONorders(order_number);或 ALTER TABLE 订单添加唯一索引 udx_order_no(order_number);。
对于主键索引,只能使用 ALTER TABLE products ADD PRIMARY KEY(product_id);这种形式,而且只能有一个。

注意组合索引的顺序,例如(col1 ,col2 ),不能单独使用col2 来检查。
把最有选择性的放在前面。
当时我没有想到这一点,但是尝试多了之后就习惯了。
全文索引用于文本搜索。
在文章(内容)上创建全文索引 fdx_content;是这样制作的。

什么时候应该建立索引?经常查询的列,例如 WHERE 子句中经常使用的列。
GROUP BY涉及的列也可以。
还有一些读多写少的表,例如统计表。
删除索引怎么办?已经很久没有使用过了。
如果查看information_schema.STATISTICS,可以看到使用率很低。
或者索引太多,写操作变慢。
必须删除与复合索引重复的单个索引。

分析工具,EXPLAIN是必备的。
例如,EXPLAIN SELECT FROM users WHERE username='test';查看类型是否为 ALL 以及有多少行。
不要盲目添加索引。
每个索引都会占用空间并影响写操作。
MySQL 5 .6 及更高版本有在线DDL,ALTER TABLE large_table ADD INDEX idx_new_column(new_column)、ALGORITHM=INPLACE、LOCK=NONE;这样,更改索引时不必完全锁定表。

误区:低版本MySQL添加索引会锁表,所以要选择时间。
有时根本不使用索引。
可能是数据量太小,或者条件LIKE'%keyword%'太模糊,优化器选择了其他索引。
还有重复索引。
如果同一列有几个相同的肯定不行。
删除索引后不需要OPTIMIZE TABLE,不要混淆。

总之,索引要看情况。
业务需求和数据库的性能都必须考虑。
使用 EXPLAIN 查看查询模式,不要添加无用的索引。
使用在线DDL来减少影响。
定期清理无用索引,并在上线前在测试环境中检查。