【问题标题】:Optimizing of database with multiple JOINs使用多个 JOIN 优化数据库
【发布时间】:2011-10-10 17:12:20
【问题描述】:

首先,关于网站和数据库结构的一些细节-

通过我的网站,您可以学习英语单词,并且您可以在每个单词上插入一个句子、一个关联、一个图像,此外 - 每个单词都有一个类别、子类别、组...

我的数据库包含大约 20 个表。任何注册到我的网站的用户都会“添加”到用户表中,比如 4000 行——我网站上的字数。我在用户过滤单词时遇到了一个严重的问题(类似“搜索”的单词,但根据 char/s & category/s & group/s 等。我的 sql 查询中有 9 个 JOIN,它需要大约 1 分钟显示结果..

JOIN 的目标 - 在表 users 内(每个用户有 4000 行/每行 = 单词)有这种样式的连接:

$this->db->join('users', 'sentences.id = users.sentence_id' ,'left');

与关联、组、图像、单词之间的绑定等相同。 users 表包括句子、关联、组的 id.. 并且与 JOIN 有一个连接。

我不知道该怎么办.. 这需要太多时间。也许问题是数据库的结构?多个连接?也许使用索引?但是如何以及在哪里?因为有时需要检索所有单词,所以索引无济于事。

我正在使用 MySQL。

【问题讨论】:

  • 你发布架构怎么样?还要描述这个过程,每个表的内容和时间。为什么单个用户会在 users 表中添加 4000 行——这听起来很奇怪?

标签: mysql sql database database-design


【解决方案1】:

首先,如果您使用了这么多连接,索引将无法拯救您(因为它们不会在大多数时间用于连接)。

您可以做一些事情。

架构设计

如果您需要 9 个连接来实现您正在做的事情,您可能需要重新考虑您的架构设计/查询!

从外观上看,您的表格似乎非常规范化,也许是第三范式?在这种情况下,考虑将您的表非规范化为一个更大的表以避免连接(连接比全表扫描更昂贵!)。有很多关于这方面的在线文档,但是这总是有成本的,因为它增加了开发的复杂性和数据冗余。此外,通过对表进行非规范化,您可以避免连接,并且可以更好地利用索引。

我也相信 MyISAM 是 MySQL 中唯一支持全文索引的存储引擎。但是它没有事务,没有表级锁定,也没有 MVCC,所以这取决于你需要什么。

资源

我建议您阅读本书High Performance MySQL。 一本非常棒的关于调优 MySQL 数据库的书

我还建议阅读有关您选择的存储引擎的官方文档。这很重要,因为每个存储引擎都非常不同! InnoDB 与 MyISAM 完全不同,MyISAM 也与 PBXT 完全不同。每种引擎都有其优点,您必须考虑哪一种适合您的情况。

【讨论】:

    【解决方案2】:

    我会画出关系模式并计算出您正在运行的查询的操作数量,然后从那里开始。大多数 DBMS 都试图隐式优化查询,但并不总是最优。您应该考虑重新排序连接,以便首先执行最严格的连接。索引可能会有所帮助,而且需要进行一些分析才能找到您正在搜索的属性。

    建立数据库来处理自然语言是一个非常具有挑战性的课题,并且有很多关于这个课题的研究。你看过马尔可夫链吗?您是否退后一步考虑过您正在尝试做的事情的计算复杂性?如果您对九次连接得出相同的结论,那么可以公平地说,这个问题对于实时应用程序来说不够可扩展。

    顺便说一句,我相信 Google App Engine 的数据存储会尝试为您索引属性,并具有隐含的可扩展性。如果您在小型 Web 服务器上运行数据库,那么使用更全面的 DBMS 部署它可能会获得更好的结果。但是,我只会将其视为最后的手段。

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 2013-10-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 2012-12-02
      • 1970-01-01
      • 2013-09-25
      • 2013-12-14
      相关资源
      最近更新 更多