当从 id 从 30000 开始计时超过 2 分钟的大表中更新和选择时
Posted
技术标签:
【中文标题】当从 id 从 30000 开始计时超过 2 分钟的大表中更新和选择时【英文标题】:when Updating & selecting from huge table where the id start from 30000 timing more than 2min 【发布时间】:2013-01-07 09:52:39 【问题描述】:我有一个包含 2 个表的数据库:第一个有超过 200 万条记录 第二个是第一个的历史表。 当我们尝试进行选择或更新并且 ID(主键)超过 30 000 时,查询的执行时间超过 1 分钟。 如果我截断并导入数据并且 id 从 1 开始,则查询需要 1 秒。 请问为什么ID > 30 000 时的延迟和任何其他解决方案?索引完成时间:1 代表 PK,另一个代表日期,另一个代表字段优先级整数 如果我从 table1 中简单地选择前 10 个 * 我有 2 分钟的延迟 PS:很多事务在第一张表上同时完成(选择、插入、更新和删除) 谢谢,
【问题讨论】:
您需要为您的问题添加更多详细信息。表结构包括现有索引、您执行的查询以及您为查询获得的查询计划。 因此,对于 ID > 30000 和的查询,对于没有 order by 子句的select top 10 ..
查询,您的性能很差。我是否正确理解了您的问题?服务器是否很忙?您是否有来自其他客户的长期交易?查询计划呢?他们告诉你什么?
set Transaction isolation level read uncommitted
、with (nolock)
等
您是否尝试过执行一些维护任务(例如 postgresql 上的 vacumm)?想到的可能导致一些性能下降问题的一件事是 ID 高于 30000 的记录具有对其他表的引用(尽管它不应该花那么长时间)。尽管如此,我可以建议您运行一些维护程序,看看会发生什么。如果问题仍然存在,请在镜像服务器上测试您的查询。
【参考方案1】:
如果您遇到锁争用,您基本上有两种选择:
在您进行查询时停止所有其他活动。这将保证数据的一致视图。 (技术上需要其他步骤来保证与其他表的一致性)。您可以通过指定with (TABLOCKX)
查询提示来做到这一点。
(您还可以使用“序列化”事务隔离级别,它会在您读取表时从头到尾逐步锁定表。您可以使用索引做一些巧妙的事情来减少这种痛苦,但这符合“高级”的条件")。
允许其他活动继续,但接受您得到的答案可能与查询进行时发生的活动不一致。也就是说,在查询期间添加的行可能会或可能不会被包括在内,在查询期间被删除的行可能会或可能不会被包括在内,并且正在更新的行可能会或可能不会, 具有前面或后面的值。此外,您可能会发现一些较晚的值包含在内,而一些较早的值不包含,因此不会在时间上保持一致。您可以使用with (NOLOCK)
提示来执行此操作。
(也可以使用“读未提交”的事务隔离级别,一般在需要的时候指定NOLOCK比较容易)。
根据您正在做的事情,任何一个选项都可能是最好的。如果您想提供粗略的数字,或某种滚动“前 10 名”用于报告/监控目的,请使用选项 2。如果您必须提供诸如会计号码、银行余额等内容,那么您必须有一个检查站在某个时刻知道确切的正确数字,请使用选项 1。这很少见 - 如果有疑问,您可能需要选项 2。
“中间”选项,读取已提交,读取快照等,尽管是默认设置,但实际上很少需要,并且可能只有在您充分了解情况以知道您是否需要它们时才应该使用它们.
【讨论】:
问题是我有不同的应用程序从同一个表中选择,但应用程序之间的选择不同,例如第一个应用程序从 table1 中选择*,其中 x=1 应用程序 2 执行select * from table1 where x=2 并在选择后应用程序处理每条记录并对其进行更新。一切正常,直到 id 字段变得超过 30000,如果我将 id 重置为从 1 开始,我们开始得到延迟,延迟消失。为什么我在 ID 很大时会有这种延迟 @user1199175,你没有道理。 200万行的表怎么ID= 2000000? @user1199175,“当我们尝试进行选择或更新并且 ID(主键)超过 30 000 时,查询的执行时间超过 1 分钟”。所以你的意思是当 ID ID从1到200万。使用查询设计器选择前 1000 名时需要超过 1 分钟,所以如果我选择全部。以上是关于当从 id 从 30000 开始计时超过 2 分钟的大表中更新和选择时的主要内容,如果未能解决你的问题,请参考以下文章
页面显示多个计时器,有开始暂停按钮来控制倒计时的开关????求大神指点