假设您有两个表:表A和表B.表A包含1亿行,表B可以包含表A中的一些(如果不是全部)行。
# Table A
,----,-------,------,---------,-------,---------,
| id | email | name | surname | score | updated |
'----'-------'------'---------'-------'---------'
# INDEXES
PRIMARY email
INDEX date_open
INDEX date_click
INDEX date_send
INDEX score
# Table B
,-------,-------,---------,
| email | score | updated |
'-------'-------'---------'
# INDEXES
PRIMARY email
INDEX score
假设您需要在两个查询中选择一个,您会选择哪一个?
REPLACE INTO `Table_B` (`email`, `score`, `updated`) SELECT `email`, `score`, `updated` FROM `Table_A`;
REPLACE INTO `Table_B` (`email`, `score`, `updated`) SELECT `email`, `score`, `updated` FROM `Table_A` WHERE `updated` = 'yes';
哪个查询会更快?在表A中向updated
添加索引会加快查询速度吗?
答案 0 :(得分:1)
我不在单个查询中执行数百万行。有些事情会出错 - 一些超时,一些缓冲限制,一些东西。然后它会失败 - 对于MyISAM来说,任务将部分完成,无法知道它从何处停止。对于InnoDB,它将花费大量时间来回滚它已部分完成的工作。
我对这个问题持怀疑态度......这是......
scores
从宽大的桌子A
复制到较窄的,较短的B
?这是多表UPDATE
。或者只是将B
重新设为SELECT .. FROM A
。B
包含“新”分数,需要将它们复制到A
?这也是一个多表UPDATE
。JOIN
。当只有分数的单独表格足够时,不执行更新表格的任务。但是......也许这不会起作用因为“并非所有”分数都来了?回到我的观点,“一次通过太大了”。您PRIMARY KEY(email)
可以轻松浏览一个表格,然后按照其他表格UPDATE
或IODKU
执行,例如1000 emails
。这是关于如何进行这种分块的讨论:
http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
请注意SELECT email FROM tbl WHERE email > $left_off ORDER BY email LIMIT 1000,1
作为查找下一个块结束的技术。