什么技术对于处理数百万条记录最有效?

时间:2008-10-08 08:12:54

标签: mysql database

我曾经拥有一个包含2500万条记录的MySQL数据库表,这使得即使是简单的COUNT(*)查询也需要一分钟才能执行。我最终制作了分区,将它们分成几个表。我要问的是,是否有任何模式或设计技术来处理这类问题(大量记录)? MSSQL或Oracle在处理大量记录方面更好吗?

P.S 上面提到的COUNT(*)问题仅仅是一个示例案例,实际上应用程序确实有一些功能和一些聚合查询(用于报告),但没有什么真正复杂的。由于表卷

,执行某些查询需要相当长的时间(分钟)

9 个答案:

答案 0 :(得分:8)

请参阅Why MySQL could be slow with large tablesCOUNT(*) vs COUNT(col)

确保您在计算的列上有索引。如果您的服务器有足够的RAM,请考虑增加MySQL的缓冲区大小。确保正确配置磁盘 - 启用DMA,不与交换分区共享驱动器或电缆等

答案 1 :(得分:7)

你要问“SELECT COUNT(*)”并不容易。

在MySQL中,MyISAM非事务引擎通过保持记录计数来优化它,因此SELECT COUNT(*)将非常快。

但是,如果您使用的是事务引擎,则SELECT COUNT(*)基本上是这样说的:

我的交易中该表中确实存在多少条记录?

为此,引擎需要扫描整个表格;它可能已经大致知道表中已存在多少条记录,但为了获得特定事务的确切答案,它需要扫描。使用MySQL innodb并不会很快,在Oracle或其他任何方面都不会很快。必须读取整个表(不包括由引擎单独存储的内容,如BLOB)

将整个桌子放在ram中会使它快一点,但它仍然不会很快。

如果您的应用程序依赖于频​​繁,准确的计数,您可能需要创建一个通过触发器或其他方式更新的汇总表。

如果您的应用程序依赖频繁,不太准确的计数,您可以使用计划任务维护摘要数据(这可能会影响其他操作的性能)。

答案 2 :(得分:4)

大型表的许多性能问题都与索引问题或缺少索引相关。我肯定会确保您熟悉索引技术以及您计划使用的数据库的细节。

关于巨大的表上的慢计数(*),我假设您在MySQL中使用了InnoDB表类型。我在MySQL下使用MyISAM有一些超过1亿条记录的表,而且计数(*)非常快。

特别是关于MySQL,InnoDB和MyISAM表之间甚至存在轻微的索引差异,这两种表是最常用的表类型。值得了解每种方法的优缺点以及如何使用它们。

答案 3 :(得分:1)

您需要什么样的数据访问权限?我使用了HBase(基于Google的BigTable)加载了大量数据(约3000万行)作为应用程序的后端,可以在几秒钟内返回结果。但是,如果您需要“实时”访问(即为网站供电),这并不合适。如果你习惯于面向行的DBMS,它的面向列的性质也是一个相当激进的变化。

答案 4 :(得分:1)

整个桌子上的数量(*)实际上是你经常做的事吗?

InnoDB必须进行全表扫描来计算行数,如果计算所有这些行是你真正想做的事情,这显然是一个主要的性能问题。但这并不意味着桌面上的其他操作会很慢。

使用正确的索引,MySQL将非常快速地从比这大得多的表中检索数据。索引的问题在于它们会损害插入速度,特别是对于大型表,因为一旦索引所需的空间达到某个阈值,插入性能就会急剧下降 - 可能是它将保留在内存中的大小。但是如果你只需要适度的插入速度,那么MySQL应该做你需要的一切。

任何其他数据库在检索速度和插入速度之间都会有类似的权衡;它们可能会或可能不会更好地适用于您的应用。但是在尝试其他数据库之前,我会首先考虑正确获取索引,并重写您的查询。对于它的价值,我们最初选择MySQL是因为我们发现它表现最佳。

请注意,MySQL中的MyISAM表存储了表的总大小。他们认为这是因为它在某些情况下对优化器有用,但副作用是整个表上的count(*)非常快。这并不一定意味着它们比InnoDB更快。

答案 5 :(得分:1)

我在This Stackoverflow Posting中详细回答了一个类似的问题,描述了两个系统架构的优点。在某种程度上,它是从数据仓库的角度来看的,但许多差异在事务系统上也很重要。

但是,2500万行不是VLDB,如果遇到性能问题,您应该寻求索引和调优。您不需要去Oracle支持2500万行数据库 - 在您真正进入VLDB领域之前,您已经有大约3个数量级。

答案 6 :(得分:1)

你要求的是一本值得回答的书,因此我建议你买一本关于数据库的好书。有很多

为了帮助您入门,以下是一些数据库基础知识:

首先,您需要一个出色的数据模型,不仅基于您需要存储的数据,还基于使用模式。 良好的数据库性能始于良好的架构设计。

其次,根据预期的查找和更新需求在列上放置标记,因为更新性能经常被忽略。

第三,如果可能的话,不要将函数放在where子句中。

第四,使用质量设计的-ahem- RDBMS引擎。我会恭敬地提出,虽然它在最近有了很大的改进,但是mysql没有资格。 (向那些希望争辩的人致歉,最近终于取得了成绩。)不再需要在高价和高质量之间做出选择; Postgres(又名PostgreSql)是开源的,非常棒 - 并且所有插件都可以满足您的需求。

最后,了解您要求数据库引擎做什么 - 获得对内部的一些洞察力 - 这样您就可以更好地判断哪些事情是昂贵的以及为什么。

答案 7 :(得分:0)

我要去第二个@Mark Baker,并说你需要在你的桌子上建立索引。

对于除您选择的查询以外的其他查询,您还应该知道使用诸如IN()之类的结构比查询中的一系列OR语句更快。您可以采取许多小步骤来加速个人查询。

答案 8 :(得分:0)

使用此数量的记录,索引是性能的关键,但编写查询的方式也会产生很大的影响。具体的性能调优方法因数据库而异,但一般情况下,避免返回比实际需要更多的记录或字段,确保所有连接字段都被索引(以及常见的where子句字段),避免使用游标(尽管我认为这不太正确在Oracle中比SQL Server我不了解mySQL)。

硬件也可能成为瓶颈,特别是如果您在同一台机器上运行数据库服务器以外的东西。

性能调优是一个非常技术性的主题,并且无法以这样的格式得到很好的回答。我建议你拿一本性能调优书并阅读它。这是mySQL的一个链接 http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716