交换 ms-sql 表
我想以最好的方式交换到桌子。
我有一个 IpToCountry 表,并且每周根据我导入的外部 CSV 文件创建一个新表。
我发现进行切换的最快方法是执行以下操作:
sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go
这样做的问题是,在两者之间可能仍会访问该表。
如何在 SQL 中解决这个问题?
考虑使用 sp_getapplock 和 sp_releaseapplock,但我希望尽可能快地从表函数中读取数据。
I want to swap to tables in the best possible manner.
I have an IpToCountry table, and I create a new one on a weekly basis according to an external CSV file which I import.
The fastest way I've found to make the switch was doing the following:
sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go
The problem with this is that the table might still be accessed in between.
How do I approach this problem in SQL?
In considered using sp_getapplock and sp_releaseapplock, but I want to keep the read from the table function as quick as possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
假设您无法更新/插入现有表,为什么不使用 查看?
例如,您最初可能将数据存储在名为 IpToCountry20090303 的表中,您的视图将如下所示:
当新数据传入时,您可以创建并填充 IpToCountry20090310 em> 表。 填充表后,只需更新您的视图:
切换将完全是原子的,不需要任何显式锁定或事务。 视图更新后,您可以简单地删除旧表(如果您愿意,也可以保留它)。
Assuming that you're unable to update/insert into the existing table, why don't you wrap all access to the table using a view?
For example, you might initially store your data in a table called IpToCountry20090303, and your view would be something like this:
When the new data comes in, you can create and populate the IpToCountry20090310 table. Once the table is populated just update your view:
The switch will be completely atomic, without requiring any explicit locking or transactions. Once the view has been updated, you can simply drop the old table (or keep it if you prefer).
我在让分区函数大规模工作时遇到了问题。 CREATE 和 DROP PARTITION 是阻塞操作,您对阻塞几乎没有控制权,如果它无法获得锁定,它将失败,严重级别为 16,并终止您的连接 - 如果不重新建立连接,您将无法捕获并重试该连接连接。 但它可能对你来说效果很好。 另外,需要 MSS 企业版,不能使用 SE——对于一些较小或更注重成本的商店来说可能太多了。
我还发现视图重定义会在系统表和对象上大规模阻塞(在我的例子中,=事务量+不断插入的数据量),因此这些操作可能会在重新索引和 DTCC 等方面陷入死锁——在一种情况下,特别是 SSMS 中的用户(在所有事情中)尝试浏览对象资源管理器中的视图(有人需要告诉那些人有关 READPAST 的信息)。 同样,您的里程可能会有所不同。
相比之下,sp_rename 在规模上对我来说效果很好:它使您可以控制锁定及其范围。 要解决交换之前的阻塞问题,请尝试如下所示。 从表面上看,这似乎在高容量时具有相同的规模问题......但我在实践中还没有看到它。 所以,对我有用......但同样,每个人的需求和经历都是不同的。
I've had problems getting partitioning functions to work at scale. CREATE and DROP PARTITION are blocking operations, and you have little control over the blocking, and if it can't get a lock it will fail with a severity level 16 and kill your connection -- which you can't trap and retry without reestablishing the connection. But it might work just fine for you. Also, MSS Enterprise Edition is required, you can't use SE -- might be too much for some smaller or more cost-concerned shops.
I've also found the view redef to block at high-scale (= transaction volume + sheer volume of constantly-inserted data, in my case) on sys tables and objects, so those operations can deadlock on things like reindexing and DTCCs -- and in one case, specifically with a user in SSMS (of all things) trying to browse views in the Object Explorer (somebody needs to tell those guys about READPAST). Again, your mileage may vary.
In contrast, the sp_rename works well for me at scale: it gives you control over the locking and the scope of it. To solve the blocking issue prior to the swap, try it as shown below. At face value this would seem to have the same scale issue at high volume... but I haven't seen it in practice. So, works for me... but again, everybody's needs and experiences are different.
实现您想要实现的目标的另一种方法是使用表分区,这是 SQL Server 企业版中提供的一种技术。
表名可以保持不变。 表导入完成后,您只需切换出包含旧数据的分区并切换到新分区即可。
以下白皮书包含您入门所需的所有信息。
http://msdn.microsoft.com/en-us/library/ms345146。干杯
,约翰
Another method to implement what you are looking to achieve would be the use of table partitioning, a technique that is available in the Enterprise Edition of SQL Server.
The table name can remain the same. After your table import is complete, you just simply switch out the partition containing your old data and switch in the new partition.
The following White Paper contains all the information you would need to get started.
http://msdn.microsoft.com/en-us/library/ms345146.aspx
Cheers, John
IpToCountryOld 会发生什么情况? 你把它扔掉吗? 在这种情况下,为什么不截断 IpToCountry 并导入我的新数据。
如果需要保留数据,如何将加载日期存储在表中并将“当前”加载日期存储在 WHERE 子句中使用的某个位置? 然后,当数据成功加载时,切换当前日期。
你没有说你正在使用哪个数据库,所以我不知道这有多大用处,但是你有任何引用该表的存储过程吗? 请注意,在某些平台上,SP 是使用对表的内部引用进行编译的,这些表不会因重命名而更改,因此存在 SP 在不重新编译的情况下无法获取新数据的风险。 对于视图和存储的解析查询也是如此。
What happens to IpToCountryOld? Do you throw it away? In which case, why not truncate IpToCountry and import my new data.
If you need to keep the data, how about storing the load date on the table and storing the "current" load date somewhere to be used in a WHERE clause? Then you switch the current date when the data is successfully loaded.
You don't say which DB you're using, so I don't know how much use this is, but do you have any stored procedures that reference the table? Be warned that on some platforms SPs are compiled using internal references to tables that will not change with a rename, so there's a risk that SPs won't pick up your new data without a recompile. The same can be true for views and stored parsed queries.
下班时间不能导入一张表吗?
或者为什么不直接进行数据更新,即更新现有记录并在循环导入数据时逐条记录添加任何新记录。 这将使表保持活动状态并减少添加和删除完整表的总体影响。
导入的数据结构、表设计、格式、PK等是什么? 由此我们或许能够给您一个更好的答案。
Can you not do the import to the one table during off hours?
Or why not just do a data update, ie update the existing records and add any new ones on a record by record basis as you loop to import the data. This would allow the table to stay live and reduce the overall impact of adding and dropping full tables.
What is the structure of the data being imported, table design, format, PK, etc? From that we may be able to give you a better answer.
刚刚在临时表上遇到了类似的问题,该表在使用适当的锁进行扩展时遇到了问题。
在任何引用表的地方,您都可以调用存储过程来询问表名称。
存储过程可以根据提供的参数选择创建新表或返回旧表。
Just ran into a similar issue working on a staging table that had issues scaling with proper locks.
Everywhere your table is referenced you could call a stored procedure asking for the table name.
The stored procedure would optionally create the new table(s) or return the old tables depending on the parameters provided.