对于Myisam 类型的表,可以通过以下方式快速的导入大量的数据。 ALTER TABLE tblname DISABLE KEYS; loading the data ALTER TABLE tblname ENABLE KEYS; 这两个命令用来打开或者关闭Myisam 表非唯一索引的更新。在导入大量的数据到一个非空的Myisam 表时,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的Myisam 表,默认就是先导入数据然后才创建索引的,所以不用进行设置。
表级锁在下列几种情况下比行级锁更优越:很多操作都是读表;在严格条件的索引上读取和更新,当更新或者删除可以用单独的索引来读取得到时;UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;DELETE FROM tbl_name WHERE unique_key_col=key_value;SELECT 和INSERT 语句并发的执行,但是只有很少的UPDATE 和DELETE 语句;很多的扫描表和对全表的GROUP BY 操作,但是没有任何写表。
行级锁定的优点:当在许多线程中访问不同的行时只存在少量锁定冲突;回滚时只有少量的更改;可以长时间锁定单一的行。行级锁定的缺点:比页级或表级锁定占用更多的内存;当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁;如果你在大部分数据上经常进行GROUP BY 操作或者必须经常扫描整个表,比其它锁定 明显慢很多;用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。
如何减少锁冲突。对Myisam 类型的表:Myisam 类型的表可以考虑通过改成Innodb 类型的表来减少锁冲突;根据应用的情况,尝试横向拆分成多个表或者改成Myisam 分区对减少锁冲突也会有一定的帮助。对Innodb 类型的表:首先要确认,在对表获取行锁的时候,要尽量的使用索引检索纪录,如果没有使用索引访问,那么即便你只是要更新其中的一行纪录,也是全表锁定的。要确保sql是使用索引来访问纪录的,必要的时候,请使用explain 检查sql 的执行计划,判断是否按照预期使用了索引;由于mysql 的行锁是针对索引加的锁,不是针对纪录加的锁,所以虽然是访问不同行的纪录,但是如果是相同的索引键,是会被加锁的。应用设计的时候也要注意,这里和Oracle 有比较大的不同;当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,当表有主键或者唯一索引的时候,不是必须使用主键或者唯一索引锁定纪录,其他普通索引同样可以用来检索纪录,并只锁定符合条件的行;用SHOW INNODB STATUS 来确定最后一个死锁的原因。查询的结果中,包括死锁的事务的详细信息,包括执行的SQL 语句的内容,每个线程已经获得了什么锁,在等待什么锁,以及最后是哪个线程被回滚。详细的分析死锁产生的原因,可以通过改进程序有效的避免死锁的产生;如果应用并不介意死锁的出现,那么可以在应用中对发现的死锁进行处理;确定更合理的事务大小,小事务更少地倾向于冲突;如果你正使用锁定读,(SELECT … FOR UPDATE 或… LOCK IN SHARE MODE),试着用更低的隔离级别,比如READ COMMITTED;以固定的顺序访问你的表和行,则事务形成良好定义的查询并且没有死锁。