我会通过将巨大的表分成几个小表来加速关系数据库吗?

时间:2015-08-05 12:03:28

标签: database relational-database

假设有一个巨大的表,其中包含10亿行,我使用哈希函数将主键作为参数拆分为1000个表,其中包含100万行。查询和更新的速度会更快吗?

2 个答案:

答案 0 :(得分:1)

答案是:它取决于数据,分区,查询,尤其是索引。

如果按日期拆分,这样的分区是有意义的。历史数据通常以这种方式从事务存储中移出到报告或仓库数据库中。

我想知道你是否需要索引。您应该在WHERE子句中的列上有索引。

对慢查询进行EXPLAIN PLAN并查找表扫描。

十亿行不是特别的。

答案 1 :(得分:1)

通常在INSERT / UPDATE / DELETE上保持索引更新的开销,数据库引擎应该有足够的内存来保存缓冲区中的所有索引和数据,以避免冗余的I / O.知道每个表的索引和数据大小(MySQL)会很有帮助:

SET @db_name = 'you_database';

SELECT
  TBname,
  CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(102,pw),3),',',''),17,' '),' ', SUBSTR(' KMGTP',pw,1),'B') "Data Size", 
  CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(102,pw),3),',',''),17,' '),' ', SUBSTR(' KMGTP',pw,1),'B') "Index Size",
  CONCAT(ROUND(B.ISize * 100 / B.DSize), ' %') "Percentage", 
  CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(102,pw),3),',',''),17,' '),' ', SUBSTR(' KMGTP',pw,1),'B') "Table Size"
FROM 
  (SELECT table_name TBname, data_length DSize, index_length ISize, data_length+index_length TSize 
     FROM information_schema.tables WHERE table_schema = @db_name) B,
   (SELECT 3 pw) A ORDER BY ISize DESC, DSize DESC

维基百科says

  

索引是任何可以提高性能的数据结构   抬头。有许多不同的数据结构用于此   目的。涉及查找的复杂设计权衡   性能,索引大小和索引更新性能。很多指数   设计表现出对数 O(log(N))查找性能   应用程序可以实现平坦的 O(1)性能。

如果数据库表的数量与文件名的数量相对应,请注意以下事项:

  • 免费索引节点数(df -i)
  • 打开文件数(cat / proc / sys / fs / file-max)

就O(1)算法而言,复杂度数据库的大小并不重要,但除非您的数据和索引适合内存,否则瓶颈就是磁盘I / O(即使是SSD磁盘)。从另一方面来看,数据库配置可能需要完全符合ACID,最终会频繁刷新到磁盘,然后在负载下的较大数据库上出现性能下降。

回到原始问题。将一个大表拆分成多个小表是有意义的,以加快索引管理,从而在小数据集上表现更好(并消耗更少的内存)。如果很难找到分片键,您可以考虑使用月份和年份的替代命名约定作为表名后缀(posts - > posts_2015_06,posts_2015_07,posts_2015_08)或归档策略(posts - > posts_archive,posts_fresh)。它取决于针对历史数据发生的INSERT / UPDATE / DELETE请求的数量。