MySql:使用长组合 PK 列表对多行进行操作
考虑到我在与 ODBC 连接的客户端应用程序中有一长串键,那么在 MySql 中处理多行的好方法是什么?
注意:我的经验主要是 SQL Server,所以我了解一点,但不是专门了解 MySQL。
任务是从 9 个表中删除一些行,但我可能有超过 5,000 个密钥对。
我从简单的方法开始,循环遍历所有键并针对每个表为每个键提交一条语句,例如:
DELETE FROM Table WHERE Key1 = 123 AND Key2 = 567 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 124 AND Key2 = 568 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 125 AND Key2 = 569 -- and 8 more tables
...
除了,这会产生 45,000 个单独的语句,您可以想象这有点慢。
那么,不用担心我在前端使用的编程语言,有什么好方法可以提交列表,以便我可以加入并立即或至少批量执行操作?到目前为止,我的想法如下:
创建一个临时表并插入其中,然后加入。我很乐意查找 MySQL 的语法来创建临时表,但是这是一个好的方法吗?
假设我确实使用临时表,填充临时表的最佳方法是什么? 5000 个
INSERT Table VALUES ()
语句?选择 123, 456 联合所有选择 124, 457
?我刚刚测试了 MySql 允许这种不针对表发出的 SELECT。但是如果列表太长,SQL Server 最终会崩溃,那么这在 MySQL 中是一个好方法吗?我应该一次将列表保持在几百个吗?--CREATE Temp Table(我还不知道MySql中的语法) 插入临时表 选择 123, 456 联合所有选择 124, 457 联合所有选择 125, 458 删除T 从 药片 INNER JOIN TempTable X ON T.Key1 = X.Key1 AND T.Key2 = X.Key2
XML。我发现 MySQL 5.1 有一些 XML 函数,但从粗略搜索来看,它似乎不支持将 XML 文本块转换为行集以进行连接。这是真的吗?对我来说,将值转换为 XML 非常容易。
虚拟分割操作。我认为在 MySql 中可能存在某种过程语言。在 SQL Server 中,我可以编写一些自定义代码来解析字符串并将其转换为行集:
创建过程 DoStuff @KeyString varchar(max) 作为 声明 @Keys 表 ( 键 1 整数, 键2整数, 主键聚集(Key1、Key2) ) 声明@Pos int 而@Pos < Len(@KeyString) 开始 -- 循环搜索@KeyString 中的分隔逗号 -- 并将已解析的标记对插入表变量@Keys 结尾 删除T 从 药片 内连接 @Keys K ON T.Key1 = K.Key1 AND T.Key2 = K.Key2
由于我不熟悉 MySQL,我真的不知道首先要调查哪种可能性,并且我希望得到一些帮助来帮助我做出错误的决定和/或以艰难的方式学习。
What's a good way to work with many rows in MySql, given that I have a long list of keys in a client application that is connecting with ODBC?
Note: my experience is largely SQL Server, so I know a bit, just not MySQL specifically.
The task is to delete some rows from 9 tables, but I might have upwards of 5,000 key pairs.
I started out with the easy way of looping through all my keys and submitting a statement for each one against each table, such as:
DELETE FROM Table WHERE Key1 = 123 AND Key2 = 567 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 124 AND Key2 = 568 -- and 8 more tables
DELETE FROM Table WHERE Key1 = 125 AND Key2 = 569 -- and 8 more tables
...
Except, that comes out to 45,000 separate statements, which as you can imagine is a bit slow.
So, without worrying about the programming language I'm using on the front end, what's a good way to submit the list so that I can JOIN and do the operation all at once or at least in large batches? Here are my ideas so far:
Create a temp table and insert to it, then join. I'll happily look up the syntax for MySQL to create a temp table, but is that a good route to go?
Assuming I do use a temp table, what's the best method for populating a temp table? 5000
INSERT Table VALUES ()
statements?SELECT 123, 456 UNION ALL SELECT 124, 457
? I just tested that MySql allows this kind of SELECT that is not issued against a table. But SQL Server eventually blows up if the list gets too long, so is this a good way in MySQL? Should I just keep the list to a few hundred at once?--CREATE Temp Table ( I do not know the syntax in MySql yet) INSERT INTO TempTable SELECT 123, 456 UNION ALL SELECT 124, 457 UNION ALL SELECT 125, 458 DELETE T FROM Table T INNER JOIN TempTable X ON T.Key1 = X.Key1 AND T.Key2 = X.Key2
XML. I see MySQL 5.1 has some XML functions, but from a cursory search it doesn't appear to support turning a chunk of XML text into a rowset to join against. Is that true? It is extremely easy for me to get the values into XML.
A virtual split operation. I presume in MySql that there's some kind of procedural language possible. In SQL Server I could write some custom code that parses a string and turns it into a rowset:
CREATE PROCEDURE DoStuff @KeyString varchar(max) AS DECLARE @Keys TABLE ( Key1 int, Key2 int, PRIMARY KEY CLUSTERED (Key1, Key2) ) DECLARE @Pos int WHILE @Pos < Len(@KeyString) BEGIN -- loop to search for delimiting commas in @KeyString -- and insert pairs of parsed tokens to table variable @Keys END DELETE T FROM Table T INNER JOIN @Keys K ON T.Key1 = K.Key1 AND T.Key2 = K.Key2
Since I'm unfamiliar with MySQL, I really don't know which possibility to investigate first, and I would appreciate some help to save me from making a poor decision and/or learning the hard way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将使用临时表解决方案,并将其连接到 DELETE 语句中的每个主表。因此,您只需执行九次删除,每个表一次。
创建临时表
< /a>使用
加载数据本地INFILE
使用MySQL的多表删除
DELETE
语法。回复您的评论:
CREATE TABLE
上的 MySQL 文档说明如下:这非常清楚!
关于加载数据,您可以使用
INSERT
来完成。 5000 行没什么大不了的。我使用 PHP 脚本将数百万行(例如 StackOverflow XML 数据转储)加载到 MySQL 中,这只需要大约 20 分钟。我使用准备好的语句,然后使用参数执行它。I would use the temp table solution, and join it to each main table in the
DELETE
statements. So you only have to do nine deletes, one for each table.CREATE TEMPORARY TABLE
Load a file of tab-separated data into the temp table using
LOAD DATA LOCAL INFILE
Delete using MySQL's multi-table
DELETE
syntax.Re your comment:
The MySQL docs on
CREATE TABLE
say the following:That's pretty clear!
Regarding loading the data, you could just do it with
INSERT
. 5000 rows is no big deal. I use a PHP script to load millions of rows (e.g. the StackOverflow XML data dump) into MySQL and that only takes about 20 minutes. I use a prepared statement and then execute it with parameters.