在过去的几个月里,我们已经将一些桌子从MYiSAM迁移到了InnoDB。理论上,我们在行锁定方面做到了这一点,因为我们通过多个web-scraping实例更新了各个行。我现在在我的slow_query_log(10s)中建立了数以万计的slow_queries。和很多全表扫描。我有事件非常简单的更新到一行(更新4或5列)需要28秒。 (我们的i / o和效率非常好,失败/中止尝试非常低<0.5%)
我们更新的两个表都有ID(int 11)作为主键。在InnoDB中,主键是聚簇键,因此写入以ID顺序索引的磁盘。但是我们最重要的两个记录标识列是BillsofLading
和Container
(都是varchar22)。我们的大多数DML查询都会根据这两列查找记录。我们还有BillsofLading
和container.
的索引
我理解它的方式,InnoDB在创建这两个二级索引时也使用主键。
所以,我可以有ID
= 1和BillsofLading
='z'的记录,另一条记录ID
= 9且BillsofLading
='a' 。使用InnoDB索引,当基于SELECT BillsofLading
='a'更新记录时,由于索引基于ID
,我是否仍然不需要进行全扫描以找到'a'?
提前感谢您帮助解决逻辑问题!
答案 0 :(得分:1)
不,假设MySQL选择使用您的BillsofLading
索引,您的示例不应要求完整扫描。你说
我理解它的方式,InnoDB在创建这两个二级索引时也使用主键。
这是正确的,但这并不意味着你的意思。
InnoDB的主键(PK)就像是人类的行号。它是InnoDB唯一能够唯一识别行的方法。因此,二级索引的作用是将目标列的每个值映射到与该值匹配的所有PK(即行号)。因此,MySQL可以快速跳转到你关心的BillsofLading
,然后只扫描你想要的那些行(PK)。
答案 1 :(得分:0)
您是否严重降低了key_buffer_size并将innodb_buffer_pool_size设置为可用内存的70%左右?
MyISAM和InnoDB之间存在许多细微差别。在这个答案中列出的内容太多了,你所说的一切都没有想到任何特定的问题。我建议您查看Converting MyISAM to InnoDB以查看可能导致问题的原因。