我有两张桌子
表1:
column1: varchar(20) column2: varchar(20) column3: varchar(20)
表2:
column1: varchar(20) column2: varchar(20) column3: varchar(20) <- empty
column1和column2在table1
两个表都有2000万行
我需要通过匹配column3
&amp;来填充table2
column1
column2
从table2
到column1
&amp;来自column2
的{{1}},然后从table1
获取column3
中的值,并将其放入table1
的{{1}}。 column3
&amp; table2
可能不完全匹配,因此我使用的查询是:
column1
此查询永远不会完成。我让它运行了2周,仍然没有产生任何结果。它使用一个100%的CPU核心,几乎没有SSD IO,显然需要以某种方式进行优化。
我对任何有关查询优化,索引优化甚至DBMS优化(甚至迁移,如果它有帮助)的建议持开放态度,因为我需要在将来更频繁地进行这样的查询。
EDIT1
有很多优化指南,请使用谷歌。您可以增加config(InnoDB)中的线程。对于Update本身,我建议先创建一个temp_table,然后复制到db2
我知道但是用这些指南无法完全解决我的情景。我也知道,对于这个问题(巨大的数据库,性能,瓶颈,查询设计)的组合的所有可能排列的问题都存在,也在stackoverflow上。然而,直到今天,我无法弄清楚这个特定问题组合的最佳方法是什么,并希望在这里获得帮助。话虽如此: - 更多线程需要分片或分区才能使用多个CPU核心,如果我能用其他方法解决问题,我想避免 - 你怎么建议在这里创建这样的临时表?
如果不使用外卡字符,为什么要使用like运算符?用=替换它们。另外,在每个表中where条件的3列上是否有多列索引?请分享解释的输出,以及2个表中的任何现有索引。
我猜你说数据库但是你在谈论桌子,对吗?
确切地说,抱歉这个混乱。
您编写的查询将执行20米x 20米的查找(对于表1中的每一行,查找表2中的所有行)。如果你有一个SSD或一个好的CPU,你就无法写入任何内容并期望它能够正常工作。如果你到了这一点,那么在开始编写SQL之前是时候考虑了。您需要做什么,您可以使用哪些工具以及您不知道的中间部分 - 这些是您每次发布400之前需要回答的问题十亿查询查询。
这就是我面临的情景。我不希望它像目前一样工作,说实话,所以我正在寻找可能使这个成为可解决方案的指针。基本&#34;更新它,匹配&#34;查询显然不适用于此处。所以我想找到一种更先进的解决方案。任何批评都是非常受欢迎的,所以感谢您的投入。你会怎么建议继续这里?
EDIT2
给我们一些样本值和非精确比较。
表1:
column2
表2:
UPDATE table1, table2
SET table2.column3 = table1.column3
WHERE table2.column1 LIKE table1.'%column1%' AND
table2.column2 LIKE table1.'%column2%';
这里,LIKE查询将填充表2的两行,如果它匹配&#34; Doe _&#34;为&#34; Doe&#34;。但是通过写下来,我只是意识到LIKE查询在这里没有选项,因为变量不会约束到表1中column2的后缀,而是需要各种可能的喜欢(两列的前导和尾随变体)在两个表中)。这反过来会增加所需匹配的数量。 所以,让我们忘记LIKE并专注于精确匹配。
FULLTEXT和LIKE彼此无关。
&#34;可能不完全匹配&#34; - 您将需要更多限制这种非限制。否则,任何查询尝试都将持续数周。
t2.c1 LIKE CONCAT(&#39;%&#39;,t1.c1,&#39;%&#39;)要求对t2的每一行检查t1行?这是400万亿次测试。没有硬件可以在合理的时间内完成。
FULLTEXT与&#34;单词&#34;一起使用。如果你的c1和c2是单词串,那么有一些希望使用FULLTEXT。 FULLTEXT比LIKE快得多,因为它具有基于单词的索引结构。
然而,即使FULLTEXT也没有接近t2.c1 = t1.c1的速度。仍然需要复合INDEX(c1,c2)然后它将是一个表的全表扫描(20M行),以及通过BTree索引到另一个表的20M探测。这就像40M操作 - 比LIKE好400T。
为了继续,请仔细考虑您的定义&#34;可能不完全匹配&#34;并展示你可以忍受的最佳。
好的,既然我决定放弃LIKE要求,你究竟打算用什么作为索引? 我这样读了你的帖子:
+---------+---------+-------------+---------+---------+---------+
| column1 | column2 | column3 | column4 | column5 | columnN |
+---------+---------+-------------+---------+---------+---------+
| John | Doe_ | employee001 | xyz | 12345 | ... |
| Jim | Doe | employee002 | abc | 67890 | ... |
+---------+---------+-------------+---------+---------+---------+
这是对的吗?
但有两个后续问题: 1)您的意见中的更新是否像创建新表一样快,更快或更慢,即:
+---------+---------+---------+
| column1 | column2 | column3 |
+---------+---------+---------+
| John | Doe | |
| Jim | Doe | |
+---------+---------+---------+
2)indizes和/或匹配是否区分大小写?如果是,可以调整查询而无需更改column1&amp; column2到所有大写(或全部小写)?
答案 0 :(得分:0)
t2.c1 LIKE CONCAT('%', t1.c1, '%')
和FULLTEXT
彼此无关。
&#34;可能不完全匹配&#34; - 您将需要更多限制这种非限制。否则,任何查询尝试都将持续数周。
FULLTEXT
要求针对t2的每一行检查t1行;那400个万亿测试。没有硬件可以在合理的时间内完成。
FULLTEXT
适用于&#34;字&#34;。如果你的c1和c2是单词串,那么有一些希望使用LIKE
。 FULLTEXT
比t2.c1 = t1.c1
快得多,因为它具有基于单词的索引结构。
然而,即使INDEX(c1, c2)
也不在LIKE
的速度附近。仍然需要复合 WHERE CONCAT(t1.c1, t1.c2) = CONCAT(t2.c1, t2.c2)
然后它将是一个表的全表扫描(20M行),以及通过BTree索引到另一个表的20M探测。这就像40M操作 - 比WHERE t1.c1=t2.c2 AND t1.c2 = t2.c2
的400T好很多。
为了继续,请仔细考虑您的定义&#34;可能不完全匹配&#34;并展示你可以忍受的最佳。
修改强>
INDEX(c1,c2)
很多比说{{1}}更糟糕。后者将与{{1}}一起快速运行。
答案 1 :(得分:-1)
试试这个: 1.在db1和db2中添加一个新列,其中字符在column1和column2中永远不会出现,例如 @
ALTER TABLE `db1` ADD `column4` VARCHAR(40) NOT NULL ;
UPDATE db1 SET column4 = column1 + '@' + column2
2。对db2执行相同的操作。然后在第4列(在db1和db2中)创建索引(BTREE)。
ALTER TABLE `db1` ADD INDEX ( `column4` ) ;
ALTER TABLE `db2` ADD INDEX ( `column4` ) ;
3。然后运行下一个查询:
UPDATE db1, db2 SET db2.column3 = db1.column3 WHERE db1.column4 = db2.column4;
它应该跑得足够快。 当它完成后 - 只需删除column4和它的索引