从 SQL Server 高效更新 MySQL 表

发布于 2024-07-14 14:07:02 字数 1160 浏览 5 评论 0原文

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

在 MySQL 数据库中,我需要根据 SQL Server 数据库中的结果更新数千行。 MySQL 数据库附加到在 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 DB是无法修改的第 3 方应用程序编辑:我们确实可以控制 DBMS,因此我们可以进行一些轻微的修改,例如表上的触发器或新的存储过程 - 只是没有表模式更改为添加,例如,最后更新的列 - 但我想将此选项保存为最后的手段)。

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

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

We have a MySQL database (mostly read-only, so MyISAM tables) living in the data center that talks to a SQL Server DB living on-site. There is some significant latency in the WAN (upwards of 100ms); in about 6 months the SQL Server DBMS will be moving up to the data center (e.g. same gigabit LAN).

In the MySQL DB, I have several thousand rows that I need to update from results in the SQL Server Database. The MySQL DB is attached to a rails app running on Linux, so I'd like to keep the logic to migrate the data as much as possible in either shell scripts or rake/ruby tasks (we are not windows app developers so Win32 apps and the like are right out!).

It is a fairly simple process. In pseudocode:

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

Let's assume that there are several thousand rows that need updated and done so frequently (every 5 minutes). Also assume that I have no way of knowing which rows in SQL Server had an amount change (unfortunately!) so I can't limit it to just modified rows -- I have to send them all over (yuck, but the SQL Server DB is a 3rd party app that can't be modified edit: we DO have control over the DBMS, so we could do some light modification, such as a trigger on the table or a new stored procedure -- just no table schema changes to add, say, a last-updated column -- but I would like to save this option as a last resort).

How best to do this update process minimizing runtime? This process will need to run every few minutes (sooner the better) and issuing dual connections to SQL Server and MySQL from Ruby is just too slow. It could be some write table locks issued by the MyISAM engine but converting to Innodb doesn't seem to make it any faster (the system is in test and so not easy to simulate the same sort of load that production would receive, leading me to believe that it is not lock related).

I'm currently leaning towards BCP'ing a VIEW (that corresponds to the SQL Server statement above) to a file, FTP'ing to the Linux server, then using Ruby to foreach the file (and execute a LOT of serialized SQL statements), but I have to imagine there are better ways.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2024-07-21 14:07:02

您可以按照这些说明将 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 表,可能会有更智能的方法来确定哪些数据已更改,这将使用更少的资源,但这只是一个开始。

You can add MySQL as a linked server to SQL Server following these instructions

From there you can do something like do a join between your mysql table and your mssql table where the amounts are not equal and update them accordingly.
You can then run this as a SQL Job to keep the db's in synch every 5 mins.

eg.

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

There may be smarter ways of figuring out what data has changed once you can query the mysql table from inside SQL Server that will use less resources, but this is a start.

短暂陪伴 2024-07-21 14:07:02

您也许可以向 MSSQL 端添加另一个表,以免通过缓存旧值或通过 触发(恶心)

与此正交的是,您可能会看到是否有一个 MySQL 引擎可以提供 MSSQL DB 的远程视图,例如 联合引擎 适用于 MySQL。

You might be able to add another table to the MSSQL side that lest you find updated rows by caching old values or via triggers (yuck).

Orthogonal to that you might see if there is a MySQL engine that gives a remote view of a MSSQL DB like the federated engine does for MySQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文