我有一个经常访问的表,其中包含 3 列 blob 和 4 列额外数据,这些数据未在查询中使用,只是作为结果发送到 PHP。 WHERE/ORDER BY/GROUP BY 的查询中使用了 6 个小列(big int、small int、tiny int、medium int、medium int、medium int)。
服务器的内存非常低,大约1GB,因此缓存不足以提高大型表的性能。我已经为最后 6 个小列建立了索引,但它似乎没有帮助。
将这个大表分成两部分是一个好的解决方案吗? 一个表包含最后 6 列,另一个表包含 blob 和额外数据,并使用具有一对一关系的外键将其链接到前一个表? 然后,我将在小表上运行查询,并将过滤后剩余的少量行与 blob 和额外数据连接到表中,以将它们返回给 PHP。
请注意,我已经做到了这一点,并且我设法将查询时间从 1.2-1.4 秒减少到 0.1-0.2 秒。但是我不确定我尝试过的解决方案是否被认为是良好实践,或者甚至是可取的?
最佳答案
您所实现的有时称为“垂直分区”。如果你把它发挥到极致,那么它就是列式数据库的基础,比如Vertica。
正如您所观察到的,此类分区可以显着提高查询性能。一个原因是处理一行数据需要读取的数据较少。
缺点是更新、插入和删除。由于所有数据都在一行中,这些操作基本上是原子的——也就是说,该操作仅影响数据页中的一行。 (严格来说,对于 blob 来说并非如此,因为它们被分割在多个页面中。)
当您将数据拆分到多个表中时,您需要在表之间协调这些操作,这样您就不会得到“部分”数据行。
对于用于批量插入和大量查询的数据库,这不是一个特别重要的考虑因素。将单独的数据列拆分到单独的表中是提高性能的合理方法。
关于mysql - 是否应该对包含具有一对一关系的大型 blob 的频繁访问的表进行规范化并将列拆分为两个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21137311/