两个MySQL查询之间的速度差异

时间:2017-03-14 11:28:45

标签: mysql optimization query-optimization

方案:

假设您有两个表:表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添加索引会加快查询速度吗?

1 个答案:

答案 0 :(得分:1)

在单个查询中执行数百万行。有些事情会出错 - 一些超时,一些缓冲限制,一些东西。然后它会失败 - 对于MyISAM来说,任务将部分完成,无法知道它从何处停止。对于InnoDB,它将花费大量时间来回滚它已部分完成的工作。

我对这个问题持怀疑态度......这是......

  1. scores从宽大的桌子A复制到较窄的,较短的B?这是多表UPDATE。或者只是将B重新设为SELECT .. FROM A
  2. B包含“新”分数,需要将它们复制到A?这也是一个多表UPDATE
  3. 'source'表中可能有新行。那需要IODKU。但是其他专栏呢?
  4. 这样的大量副本有时表明“错误”的架构设计。也就是说,如果您的数据流定期执行此操作,则只需将分数保存在单独的表中,并根据需要JOIN。当只有分数的单独表格足够时,执行更新表格的任务。但是......也许这不会起作用因为“并非所有”分数都来了?
  5. 回到我的观点,“一次通过太大了”。您PRIMARY KEY(email)可以轻松浏览一个表格,然后按照其他表格UPDATEIODKU执行,例如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作为查找下一个块结束的技术。