假设您有一个非常大的数据库,为了简化,我们假设它包含一个主要表,您将使用一个(且只有一个)主键字段pk
进行查找。
鉴于所有查找基本上都是SELECT * FROM table_name WHERE pk=someKeyValue
,优化此数据库以获得最快查找的最佳方法是什么?
编辑:只是更多细节 - INSERT
和UPDATE
将非常频繁,所以我不介意牺牲性能来实现更好的查找性能。
此外,似乎聚类是要走的路。您是否有使用此方法可以实现的性能提升的任何示例?这究竟是如何完成的(在任何类型的DB上)?
答案 0 :(得分:4)
如果主键是群集的,那么你就不会更快。
如果它不是群集的,并且表中的列数相对较小,那么理论上您可以创建覆盖索引来加速查询。但是,这会否定任何具有非群集主键的插入/更新性能增强功能。
如果您的主键是一个始终在增加的字段(例如,SQL Server标识,或从Oracle中的序列生成),那么集群主键无论如何都没有缺点。
答案 1 :(得分:1)
您可以做的一件事是将主键集群化,这会导致实际数据在磁盘上进行物理排序,从而加快查询速度。
这也意味着插入速度较慢,但如果选择频率比插入频率要高得多,这应该不是问题。
答案 2 :(得分:1)
如果您正在使用MySQL,则可以执行一些其他操作(除了调整缓存值之外)。表引擎可以是一个因素;例如,MyISAM被广泛认为在SELECTs上比InnoDB更快。如果这个表主要是一个查找表,并且您使用的是MySQL,那么这可能是一件好事。 (InnoDB平均来说非常好;写入比MyISAM好,而且InnoDB也不需要修复。)
答案 3 :(得分:1)
我必须为上面提出的所有内容添加两个选项(我喜欢dwc的答案)。如果你的桌子很大,你应该考虑分区。
首先,水平分区(特别是如果I / O是数据库中的瓶颈)。您创建多个文件组并在不同的硬盘驱动器上找到它们。然后,创建分区函数,分区方案以划分表并将表的各部分放在单独的HD上(如行1-499999到F:驱动器,500000-999999到G:驱动器,依此类推)。
第二,垂直分区。如果在大多数查询中选择列集(而不是*),这将有效。在这种情况下,将表中的列分为两组:首先,在所有查询中需要的字段;第二,你很少需要的领域。使用相同的主键创建两个表。当需要两个表中的列时,请在主键上使用JOIN。
(此答案适用于SQL Server 2005/2008。)
答案 4 :(得分:0)
如果您的所有查询都将基于PK,那么通过在PK上设置索引就不会获得任何额外的好处,因为它应该已经被索引编制索引。
编辑:我建议的唯一其他可能的事情是看你的桌子正常化(如果这是一个选项或必要)。通过将项目拆分为其他表格,您可以优化每个查询中的内容,并在需要时仅使用连接来提取较少使用的项目。
基于“使用单个表格的大型数据库”的有限描述,很难找到任何简单明了的优化方法,而无需查看实际存储在您的字段中的数据类型。
答案 5 :(得分:0)
答案 6 :(得分:0)
如果您使用的是Oracle,那么我建议对三种方法进行基准测试:
1表示非常普遍的方法 - 实际上它是最低的公分母,但可能意味着每行有5个以上的逻辑读取,其中一个是如果没有完全缓存的话,可能是对表的物理读取。 / p>
2将通过避免探测单独的表段来节省您的逻辑读取之一,但可能无法保存物理读取,因为IOT段将比单独的索引更大且更难缓存。
3可能会使用单个逻辑读取来获取行,但除非您将整个表缓存,否则可能会转换为物理读取。
强烈建议进行基准测试。