我有一个运行良好的应用程序很长一段时间,但最近有一些项目已经开始在慢查询日志中弹出。 所有查询都是复杂且丑陋的多连接选择语句,可以使用重构。我相信所有这些都有blob,这意味着它们会被写入磁盘。令我好奇的部分是为什么他们中的一些人有与他们相关的锁定时间。没有任何查询具有应用程序设置的任何特定锁定协议。据我所知,默认情况下,除非明确指定,否则您可以读取锁。
所以我的问题:哪些场景会导致select语句必须等待锁定(从而在慢速查询日志中报告)?假设INNODB和MYISAM环境。
磁盘交互是否可以列为某种锁定时间?如果是的话,是否有文件说明了这一点?
提前感谢。
答案 0 :(得分:0)
我不确定MySql,但我知道在SQL Server中,select语句不会读取锁。这样做将允许您读取未提交的数据,并可能看到重复的记录或完全错过记录。原因是因为如果另一个进程正在写入表,则数据库引擎可能会决定重新组织某些数据并在磁盘上进行转换。因此,它会将您已经阅读过的记录移动到最后,然后再次看到它,或者它从最后一个向上移动到您已经过去的位置。
网上有一个人实际上写了几个脚本来证明这种情况发生了,我尝试了一次,只需要几秒钟才能复制出来。当然,他以一种更有可能发生的方式设计脚本,但它证明它肯定会发生。
如果您的数据不需要准确并且肯定可以帮助防止死锁,这是可以的行为。但是,如果你正在处理一个处理类似人们钱的事情的应用程序,那就非常糟糕。
在SQL Server中,您可以使用WITH NOLOCK提示告诉select语句忽略锁定。我不确定MySql中的等价物是什么,但也许其他人会说。
答案 1 :(得分:0)
MyISAM会给你并发问题,当插入进行时,整个表被完全锁定。
InnoDB应该没有读取问题,即使写入/事务正在进行中,因为它是MVCC。
但是,仅仅因为查询在慢查询日志中显示并不意味着查询速度慢 - 多少秒,正在检查多少条记录?
将“EXPLAIN”放在查询前面,以获取查询的检查细分。
here's a good resource了解EXPLAIN(关于它的优秀MySQL文档之外)