不影响其他操作的MySql查询

Posted

技术标签:

【中文标题】不影响其他操作的MySql查询【英文标题】:MySql query with no impact on other operations 【发布时间】:2015-08-10 02:13:25 【问题描述】:

我有一个巨大的(设计不佳的)InnoDB 表,其中包含数百万条记录。当我询问这个​​人时,执行持续了几分钟。如何确保在此期间没有其他操作(查询、插入或更新)受到影响?我最不想要的就是在我的查询运行时其他人的死锁或超时。

这是实际的查询..

SELECT html FROM cms_log where class_name ='main_pages' order by date_created desc;

目前,“class_name”字段未编入索引,但我目前无法更改。

This post 建议使用

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

在运行我的查询之前。但这是一个相当古老的帖子,它只谈到锁。有人可以确认这是要走的路还是提供更好的方法来运行最无害的查询? (我也不关心脏读和幻读,我只是不想影响其他操作)。

【问题讨论】:

可以设置副本吗?然后您可以在不影响主数据库的情况下查询副本。 +如果您不介意粘贴查询,我们可以帮助您优化它 @DanLowe 提出了一个很好的观点,我将进一步说明从属中的附加索引(主索引上不存在相同的索引)是受支持的有效配置,除了唯一索引的课程,在一个地方而不是另一个地方是没有意义的......但是在主节点上适当索引的重要性不能得到足够的强调。 【参考方案1】:

所以看起来这是要走的路..

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

在查询之前执行这个似乎可以确保在这个长查询执行时没有其他操作得到可怕的“超过锁定等待超时”。

【讨论】:

【参考方案2】:

我不同意您发布的链接。将隔离级别设置为 READ UNCOMMITTED 不应使您的选择查询更快/对任何其他查询产生不同的影响。

像您在 InnoDB 中的纯选择不应该锁定任何东西(除了它们自己的内部数据结构)。

通常,SELECT 可以锁定读取、写入或无锁定。取决于上下文。在这种情况下,如果您没有明确请求锁,并且您没有更新任何内容,则不应使用行锁。

这是假设您通常运行 READ COMMITTED 或 REPEATABLE READ 隔离级别。

【讨论】:

我不同意你的不同意见。 :) 我从来没有弄清楚机制是什么,但我确定我在“线程 2”中遇到了一个令人困惑的“超过锁定等待超时”,而“线程 1”正在执行一个长时间运行的非锁定选择, 从一个不应该持有锁的事务内部。将“线程 1”更改为使用 READ UNCOMMITTED 解决了这个问题,在此之前这是一个日常的烦恼。当长时间运行的SELECT 在其他隔离级别仍在进行时,InnoDB 似乎确实做了一些事情导致其他线程等待写入。

以上是关于不影响其他操作的MySql查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL存储引擎和连接查询

给定连接上的慢 MySQL 查询何时会影响其他连接?

mysql中的慢查询会不会影响速度

MySQL数据库出现慢查询的危害

MySql翻页查询

MySQL EXPLAIN 命令: 查看查询执行计划