【问题标题】:MySQL Queries Pegging Server Resources -- Indexes aren't being usedMySQL 查询挂钩服务器资源——未使用索引
【发布时间】:2014-09-28 11:07:34
【问题描述】:

几年前我参加了一个志愿者项目。该站点是使用 Joomla 建立的,但大多数文章都是使用从非 Joomla 表中提取信息的 php 脚本呈现的。数据库现在将近 50MB,一些非 Joomla 表有 60,000 多行——我不知道它会变得这么大。即使只是拉出包含这些脚本的文章列表也需要很长时间——而现在只有大约 30 篇。我最初认为问题是因为我正在拨号,所以一切都很慢,但后来我们开始收到“资源超出”通知,所以我想我最好找出发生了什么。这不是一个高流量的网站——我们在任何一个月内获得的唯一身份访问者都少于 2,000 人。

在一个特定的例子中,我有一张表,其中按标题、作者、出版日期等列出了图书馆馆藏(书籍等)。第二张表包含这些书籍中提到的名称。我有一个 Joomla!列出在该书中找到的名称的每个出版物的文章。我还有一篇文章列出了所有书籍中的所有名字。那就是下面的查询——但即使是那些只提取大约 1,000 个条目的特定书籍的查询也非常慢。

我最初为这些表 (MyISAM) 设置了索引,但是当我回去检查时,它们并不存在。所以我认为重新配置索引可以解决问题。甚至没有——根据解释,它们甚至没有被使用。

我的一个有问题的查询如下:

SELECT *
FROM pub_surnames
WHERE pub_surname_last REGEXP '^[A-B]'
ORDER BY pub_surname_last, pub_surname_first, pub_surname_middle

解释给:

id 1
select_type SIMPLE
table pub_surnames
type ALL
possible_keys NULL
key NULL
key_len NULL
ref NULL
rows 56422
Extra Using where; Using filesort

另外,phpmyadmin 说“当前选择不包含唯一列。”

此查询的所有字段都是必需的,但我在这里读到,如果我单独列出它们会有所帮助,所以我这样做了。该表包含一个主键,并且我添加了第二个唯一索引,其中包含该表的主键以及包含有关发布本身的信息的表的主键。我还为 ORDER BY 字段添加了索引。但是当我使用 EXPLAIN 时我仍然得到相同的结果并且性能根本没有提高。

我在 Joomla! 中设置了这些表格!该站点用于连接目的的数据库,它使备份所有内容变得更加容易。我现在想知道如果我为我们的非 Joomla 表使用单独的数据库是否会有所帮助?还是只会让情况变得更糟?

我不确定从这里去哪里。

【问题讨论】:

  • 您有一篇文章,其中包含所有书籍中的所有名字?我不清楚这与查询有何关系。 “包含这些脚本的文章列表”是什么意思?在我看来(只是读到这里)你所说的关于“文章”的内容没有任何意义。您有 pub_surnames 表的密钥吗?你也没有说你使用的是什么 Joomla 版本,但这会对解决方案产生影响。
  • 文章包含 php 脚本,这些脚本根据 HoldingID 编号选择为特定书籍编制索引的姓氏。那些跑得足够快。就是上面那个有问题。是的——所有表都有主键。
  • Joomla 是 v. 2.5 我有一个菜单项列出了一个类别中的所有文章——“索引”。每本书都有自己的文章,列出了为该书编入索引的姓氏。到目前为止,我已经完成了大约 30 个。还有更多——大约有 1,200 本书——但在弄清楚问题出在哪里之前,我不想再做任何事情了。
  • 为什么文章里会有php脚本?将它们放入插件中。文章是文本而不是代码。只是事情发生的顺序......从你所说的你在呈现页面的中间这样做,当然这很慢。听起来你也没有缓存。我真的认为您需要有一个数据库,其中包含书籍字段和提到的每个名称的行。此外,如果您在文章中有文本,只需让 finder 索引它们并使用它进行查询,它会更快。不要每次都搜索,让finder正确搜索一次。
  • 我在处理事情时禁用了缓存,但是是的,实际上,缓存是启用的。图书馆的目录不断更新和更改。维护这些文章将拥有自己的生命。我不明白你对数据库的评论。

标签: mysql joomla phpmyadmin


【解决方案1】:

我认为您可能以错误的方式处理此问题。可能这是您第一次设置它时完成它的快速方法,但现在数据已经增长,您正在为此付出代价。

每次呈现页面时,您似乎都在“在”文章“内部”重新创建一个庞大的列表。即使源数据不断更新,您最好还是存储结果。 (假设我正确理解了您的数据结构。)不确切地知道您的 php 脚本在做什么使它有点复杂..实际上制作一个非常简单的组件来从其他表中读取数据可能更有意义但我认为这没有意义。

这就是我认为您可能想要做的事情。 创建一个 cron 作业(使用 Joomla 制作脚本真的很容易,去看看 jacs 存储库)并使用它来运行您的 php 正在做的任何事情。您可以安排一天一次、一小时一次或每 10 分钟一次,只要有意义。

保存结果。这些可以进入数据库表,或者您可以将它们缓存在文件系统中。或两者。或者可能让脚本更新文章,因为它们似乎已修复(您没有添加新文章等)

然后,当用户来时,您只想阅读存储在那里的文章,或者您想要一个呈现结果的组件或制作一个插件来为您管理查询。您不应该直接从文章布局内部进行查询,这是错误的,即使没有人知道它在那里。如果您必须运行查询,请使用类似于配置文件插件的内容插件,它在架构上在正确的位置执行查询。

不知道您在做什么的确切目的,很难提供更多建议,但我认为,如果您正在管理对人的搜索,您最好创建一种使用 finder 来索引和搜索结果的方法。

【讨论】:

  • 感谢您对此的帮助。你的建议给了我很多看,性能已经提高。你是对的——我做错了。谢谢! :-)
【解决方案2】:

看看下面的建议

  1. 尝试将您的数据库引擎更改为 InnoDB,这将更好地用于大型数据集。

  2. 还可以使用 RegEx 替代方法,它用于查询的“WHERE”部分,极大地影响查询执行时间。

  3. 而不是选择所有带有“*”的列,只需选择需要的列。

【讨论】:

  • 我没有使用 InnoDB,因为我需要全文搜索。在这种特殊情况下,我选择了所有列,因为我确实需要所有这些列。我快速浏览了 RegEx 问题,并将对此进行更多研究,看看它是否有帮助。谢谢。
  • 尝试更改 REGEX 部分,如果它优化了执行时间,请发表评论
  • 实际上,在这种情况下,REGEXP 更快。谢谢!
猜你喜欢
  • 2016-07-29
  • 2011-07-22
  • 2014-12-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 2020-05-02
  • 2021-08-04
  • 1970-01-01
相关资源
最近更新 更多