mysql - 从 SQL Server 高效更新 MySQL 表

标签 mysql sql-server ruby performance migration

我们有一个位于数据中心的 MySQL 数据库(大部分是只读的,所以是 MyISAM 表),它与位于现场的 SQL Server 数据库通信。 WAN 中存在一些明显的延迟(超过 100 毫秒);大约 6 个月后,SQL Server DBMS 将迁移到数据中心(例如相同的千兆局域网)。

在 MySQL 数据库中,我有数千行需要根据 SQL Server 数据库中的结果进行更新。 MySQL DB 附加到在 Linux 上运行的 Rails 应用程序,因此我想在 shell 脚本或 rake/ruby 任务 中保留尽可能多地迁移数据的逻辑(我们不是Windows 应用程序开发人员,因此 Win32 应用程序等马上!)。

这是一个相当简单的过程。在伪代码中:

SELECT id
     , amount
  FROM bank_account.on_SQL_Server
 WHERE (some logic)

FOREACH ROW:
  UPDATE bank_account.on_MySQL
     SET amount = $some_amount
   WHERE id     = $some_id

让我们假设有数千行需要更新并且更新频率如此之高(每 5 分钟一次)。还假设我无法知道 SQL Server 中的哪些行发生了数量变化(不幸的是!)所以我不能将其限制为仅修改过的行——我必须将它们全部发送过去(糟糕,但是 SQL Server 数据库是无法修改的第 3 方应用程序编辑:我们确实可以控制 DBMS,因此我们可以进行一些轻微的修改,例如表上的触发器或新的存储过程——只是没有表模式更改以添加,例如,最后更新的列 - 但我想将此选项保存为最后的手段)。

如何最好地执行此更新过程以最大限度地减少运行时间?这个过程需要每隔几分钟运行一次(越快越好),并且从 Ruby 向 SQL Server 和 MySQL 发出双连接太慢了。这可能是 MyISAM 引擎发出的一些写表锁,但转换为 Innodb 似乎并没有使它更快(系统正在测试中,因此不容易模拟生产会收到的相同类型的负载,导致我相信它与锁无关)。

我目前倾向于 BCP 将 View (对应于上面的 SQL Server 语句)发送到文件,FTP 发送到 Linux 服务器,然后使用 Ruby foreach 文件(并执行大量序列化SQL 语句),但我不得不想象有更好的方法。

最佳答案

您可以在these instructions 之后将MySQL 作为链接服务器添加到SQL Server。

从那里你可以做一些事情,比如在你的 mysql 表和你的 mssql 表之间做一个连接,其中数量不相等并相应地更新它们。 然后,您可以将其作为 SQL 作业运行,以保持数据库每 5 分钟同步一次。

例如。

SELECT * FROM mysql.dbo.bank_account myb 
INNER JOIN bank_account sqlb 
ON myb.id = sqlb.id 
AND sqlb.amount <> myb.amount

一旦您可以从 SQL Server 内部查询 mysql 表,这将使用更少的资源,可能会有更智能的方法来确定哪些数据已更改,但这只是一个开始。

关于mysql - 从 SQL Server 高效更新 MySQL 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/628447/

相关文章:

MySQL 在大表上查询速度很慢

c# - 操作数类型冲突 : varchar is incompatible with varchar(50) trying to insert in encrypted database

ruby - 如何在 ruby​​ 数组中找到整数/最大整数并返回索引位置?

ruby-on-rails - Rspec 3. #<RSpec::ExampleGroups::ConfigsAPI::GETApiConfig:0x007f84d93fbb90> 的未定义局部变量或方法 `response'

mysql - SQL - 查找每个 Actor 的名字、姓氏和科幻电影的总长度

mysql - 根据获奖产品添加行 "Type"

SQL 引用的表中没有主键或候选键

ruby-on-rails - Ruby Dir ['**/*' ] 限制?

mysql - SQL更新所有表的id

sql - 主键总是聚集的吗?