【问题标题】:Easily filterable database table with large amounts of entries具有大量条目的易于过滤的数据库表
【发布时间】:2011-06-13 13:44:53
【问题描述】:

我正在为我的项目开发问题记录器,但在分析记录的数据时遇到了问题。问题是该表增长得非常快,并且用于搜索表中数据的过滤器几乎在所有方面都可能有所不同,因为我们并不总是对相同的字段感兴趣。所以索引并不是一个真正的选择。

该表当前位于 MySQL 数据库中,结构如下:

CREATE TABLE `log_issues` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_user` int(11) DEFAULT NULL,
  `type` varchar(50) NOT NULL,
  `title` varchar(100) NOT NULL DEFAULT '',
  `message` mediumtext NOT NULL,
  `debug` mediumtext,
  `duration` float DEFAULT NULL,
  `date` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `date` (`date`,`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在我的问题是,当该表有数百万个条目时,我如何在该表上运行查询,而不必永远等待结果?例如,仅过滤用户的 id 就需要很长时间。我知道我可以在 id_user 部分放置一个索引,但我可能想将它与其他字段结合起来,或者由于查看这些日志的工具生成查询的方式,它可能无法正确利用索引。

我认为使用 MongoDB 或其他 NoSQL 数据库可能会更好,但我对它们没有任何经验。基于文档的数据库是否更容易过滤没有索引的大型数据集,或者无论数据库如何,我都会遇到这个问题?

总结一下:

我有一个包含大量数据的表,无法使用索引(至少在需要排序的情况下),我需要在不等待超过 10 秒的情况下获得结果。我可以使用哪些技术?

任何建议将不胜感激。

【问题讨论】:

  • 索引...索引...索引...还是索引!!! (使用索引不会永远过滤用户的 id)
  • 正如我所说,我知道这一点,但查询并不总是像过滤用户 id 那样简单。我需要更好的东西,如果它存在的话。

标签: mysql mongodb performance database nosql


【解决方案1】:

首先,您应该决定是否要留在 RDBMS 领域。如今,对于大多数场景来说,它已经没有多大意义了,尤其是那些具有复杂数据结构或需要大量扩展的场景。

您可能需要检查 RavenDB。您可以在数小时内获得使用它的原型,包括在那里初步学习概念。

任何地方都需要索引,当然在任何 NoSQL 中也是如此。真正的问题是创建和维护它们有多容易。使用 RavenDB,您可以获得免提索引;索引会根据您所做的查询类型自动创建。建议预先定义它们以减少陈旧性,但它们在自动创建时也是相同的索引。

我在另一个答案中看到您解决了 Mongo 的问题;好吧,使用 Raven,您不必定义索引,但它们会为您创建。

【讨论】:

  • 谢谢!这看起来很有趣,不幸的是 RavenDB 似乎只是 Windows,这对我来说是一个交易破坏者。我已经在项目中的任何地方都阻止了关系查询,因为我知道它带来的扩展问题。 MongoDB 的初始测试看起来很有希望,它以毫秒为单位提供结果,而 MySQL 以秒为单位。可惜它没有自动索引,这听起来确实是一个非常有趣的功能。
  • 是的,但它是社区提供的补丁,我对在开发人员不支持的平台上采用技术有点犹豫。虽然很遗憾,但它看起来很有趣。一定会一直关注它。
【解决方案2】:

首先,什么是“永远”?我们在这里谈了多久?

第二次开始索引。我知道你可以搜索任何字段,但是 8 个索引有什么问题?

如果您没有索引,它将进行表扫描以查找信息,这会很慢。

另外,如果您一直在一个字段上进行搜索,您可能会考虑在该字段上进行聚集索引。

编辑

另一种选择,保持您的日志表不变。然后创建一些要运行的作业(每小时?)来组织您的数据。例如,我们有一个 EventLog 表。我们只插入到该表中。然后,我们将 EventsByDate、EventsByHour、EventsByAccountId 等作为单独的表。然后将它们编入索引,然后我们点击它们来查看数据。

这允许您不定义索引,并尽可能快地插入,同时能够以合理的速度搜索数据。

【讨论】:

  • 谢谢,如果没有其他办法,我会放置索引。我只是想知道是否有另一种方法。我只真正使用过 MySQL,因为我所知道的其他数据库(无论是 SQL 还是 NoSQL)在非索引查询方面都做得更好。而“永远”意味着大约 40 秒 atm,随着表获得更多条目而增加。
  • NoSql(和 MSSQL)在没有索引的情况下不会有更高的性能。例如,如果您知道对象 id(不是上面的 int id),Mongo 会更快,但仅在这种情况下(这是因为我相信默认情况下它已被索引。)如果没有索引,它必须搜索每条记录。您是否有理由要避免使用索引?
  • 我为我的答案添加了另一种选择。创建按相关数据分组和索引的新表。
  • 有趣,似乎或多或少符合 marr75 的建议。尽管如此,它并不完全理想。这是一个妥协,我肯定会考虑。谢谢。
  • 是的,它很相似......重点是 1 个用于插入无索引的表,以及其他具有分组/排序/索引的表以加快查找速度。您厌恶索引的原因是什么?
【解决方案3】:

您可以考虑partitioning 您的餐桌。在许多情况下,某种基于日期的分区是有意义的。否则,如果您永远不会查询多种类型,或者您可以单独管理这些类型,则可以按类型进行分区。分区的关键是永远不要跨越查询中的分区。 “永远”存在的表确实需要在某些时候进行分区或清理。很少有应用程序可以无限扩展。

【讨论】:

  • 谢谢,这看起来很有趣,虽然并不理想。我知道没有表可以无限扩展,但我应该能够毫无问题地存储几个月的数据。
  • 我不得不同意,在某些时间段内您会发现事件日志很有趣,您只需要仔细选择那将是什么,因为我可以根据经验说更大更您的应用程序的可用性越高,更改分区就越困难。祝你好运,如果您需要有关分区的更多信息或建议,请告诉我。
  • 进一步思考这个主题,您可能希望按日期和问题类型进行分区。如果这仍然不理想,我可能无法完全理解您的问题并解释 MySQL 中自动水平分区的哪些方面可能会帮助我制定另一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
相关资源
最近更新 更多