简体   繁体   English

从常量插入的表中选择

[英]Select From a table that is constantly being inserted into

How would I go about grabbing data from a table that is CONSTANTLY being inserted into (and needs to be) without causing any locking so that the inserts will continue unheeded. 我将如何从一个常量插入(并且需要)的表中获取数据而不会导致任何锁定,以便插入将继续被忽略。

I've looked around and found select with nolock option but, if I'm understanding correctly, this does not stop the lock creation, rather goes around current locks and grabs everything? 我环顾四周,发现选择nolock选项,但是,如果我理解正确,这不会阻止锁定创建,而是围绕当前锁定并抓住一切?

Thanks. 谢谢。

EDIT: This table will never be UPDATED, only INSERTS and SELECTS 编辑:此表永远不会更新,只有INSERTS和SELECTS

You can use the NOLOCK hint when selecting from the table. 从表中选择时,您可以使用NOLOCK提示。 There are some side effects like this (you can basically get a dirty read.) 有这样的副作用(你基本上可以得到脏读。)

NOLOCK issues no row locks in the query you add it to, and has no impact on the locks issued by other running queries. NOLOCK在您添加它的查询中不发出行锁,并且对其他正在运行的查询发出的锁没有影响。 NOLOCK does issue aa Sch-S lock, Schema Stability lock, which isn't going to cause you a problem. NOLOCK确实发布了一个Sch-S锁,Schema Stability锁,这不会给你带来麻烦。

I believe you have misunderstood. 我相信你误解了。 select ... with (nolock) will not acquire any locks. select ... with(nolock)将不会获得任何锁定。 That is to say, it will not block any other writes. 也就是说,它不会阻止任何其他写入。

The downside seems to be that it will include uncommitted reads, so the result may not hold it the writing transaction rolls back. 缺点似乎是它将包括未提交的读取,因此结果可能无法保持写入事务回滚。

As long as you don't mind getting dirty reads from your table this shouldn't be a problem for you. 只要你不介意从你的表中读取脏读,这对你来说应该不是问题。 Make sure that the translation isolation level is set appropriately and that your calling code (if applicable) isn't using implicit transactions and you should be fine. 确保正确设置了转换隔离级别,并且您的调用代码(如果适用)未使用隐式事务,您应该没问题。

Microsoft's Transaction Isolation Docs: http://msdn.microsoft.com/en-us/library/ms173763.aspx 微软的交易隔离文件: http//msdn.microsoft.com/en-us/library/ms173763.aspx

NOLOCK is a common, and in my opinion, abused option when running into situations like this. NOLOCK是一个常见的,在我看来,在遇到这种情况时会滥用选项。 Although it can help you overcome problems in high contention situations it can also cause difficult to track down bugs. 虽然它可以帮助您克服高争用情况下的问题,但它也可能导致难以追踪错误。 Although this is something of an ongoing argument check out http://blogs.msdn.com/b/davidlean/archive/2009/04/06/sql-server-nolock-hint-other-poor-ideas.aspx for an idea of some of the risks with using hints like this. 虽然这是一个持续的争论,请查看http://blogs.msdn.com/b/davidlean/archive/2009/04/06/sql-server-nolock-hint-other-poor-ideas.aspx的想法使用这样的提示的一些风险。

You can use NOLOCK, but I would only recommend that in cases where you know that "dirty data" is acceptable (for example, a syslog database where you know data will never be altered or deleted once it's been inserted). 您可以使用NOLOCK,但我只建议您知道“脏数据”是可接受的(例如,您知道数据在插入后永远不会被更改或删除的系统日志数据库)。 The best way to do it is to SELECT from data that is NOT being locked; 最好的方法是从未被锁定的数据中选择; can you identify rows that aren't being affected by your insert? 你能识别出不受插入影响的行吗? For example, if your data is being inserted with a CreateDate column defaulting to GETDATE(), make sure your queries pull data from BEFORE that point. 例如,如果使用CreateDate列插入数据,默认为GETDATE(),请确保查询从该点之前提取数据。

Of course, it all depends on how much data is being written and whether or not the insert statement is generating row or page or table locks... 当然,这一切都取决于正在写入的数据量以及insert语句是否生成行或页面或表锁...

One option not discussed here is to use replication. 此处未讨论的一个选项是使用复制。 If you replicate the table in question and run your queries on the replicated database, you will not block inserts/updates. 如果复制有问题的表并在复制的数据库上运行查询,则不会阻止插入/更新。 (In your case, I would use transactional replication - https://msdn.microsoft.com/en-us/library/ms151176.aspx ). (在您的情况下,我将使用事务复制 - https://msdn.microsoft.com/en-us/library/ms151176.aspx )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM