在进一步说明之前,我只想说,当你谷歌“慢joomla”或“优化joomla”时,我已经完成了所有建议。也就是说,我的网站是GZipped,我的所有css和js都经过优化和缩小,我没有运行任何不必要的组件,插件或模块(实际上几乎没有),我的图像已经过优化,缓存已打开(页面和Progressive)我正在使用Rackspace进行supah-fast云托管,我的SQL数据库位于一个单独的Rackspace服务器上。
所有这一切,我的加载时间仍然超过10-12秒,有时高达14-15秒。
来自Joomla调试:
Application 0.000 seconds (+0.000); 0.75 MB (+0.755) - afterLoad
Application 0.027 seconds (+0.027); 2.25 MB (+1.491) - afterInitialise
Application 0.040 seconds (+0.013); 3.26 MB (+1.010) - afterRoute
Application 11.986 seconds (+11.947); 5.09 MB (+1.833) - afterDispatch
Application 12.000 seconds (+0.014); 5.63 MB (+0.539) - beforeRenderModule mod_chronoforms (Tip Line)
Application 12.006 seconds (+0.005); 5.85 MB (+0.225) - afterRenderModule mod_chronoforms (Tip Line)
Application 12.008 seconds (+0.002); 5.86 MB (+0.006) - beforeRenderModule mod_custom_advanced (Sponsors)
Application 12.009 seconds (+0.002); 5.88 MB (+0.019) - afterRenderModule mod_custom_advanced (Sponsors)
Application 12.010 seconds (+0.001); 5.87 MB (-0.006) - beforeRenderModule mod_flexi_customcode (Popular Now)
Application 12.012 seconds (+0.002); 5.89 MB (+0.018) - afterRenderModule mod_flexi_customcode (Popular Now)
Application 12.012 seconds (+0.001); 5.84 MB (-0.046) - beforeRenderModule mod_articles_category (Featured Articles)
Application 12.033 seconds (+0.021); 5.97 MB (+0.127) - afterRenderModule mod_articles_category (Featured Articles)
Application 12.033 seconds (+0.000); 5.96 MB (-0.014) - beforeRenderModule mod_search (Search)
Application 12.036 seconds (+0.002); 5.98 MB (+0.022) - afterRenderModule mod_search (Search)
Application 12.036 seconds (+0.001); 5.93 MB (-0.050) - beforeRenderModule mod_acymailing (AcyMailing Module)
Application 12.044 seconds (+0.007); 6.44 MB (+0.507) - afterRenderModule mod_acymailing (AcyMailing Module)
Application 12.157 seconds (+0.114); 6.72 MB (+0.289) - afterRender
afterDispatch的(+11.947)让我觉得它可能是MySQL查询的一个问题,所以我开始通过PHPMyAdmin运行一些长(长,长)的。
我发现像这样的查询(第一个为类别 - 博客视图加载了8篇文章 - 据我所知,第二个进行相同的搜索,减去LIMIT
,以允许每次加载时,需要2到3秒的EACH才能完成,并且每次加载页面时都会有40多个奇怪的查询(尽管绝大多数查询都不笨重):
SELECT a.id, a.title, a.alias, a.introtext, a.checked_out, a.checked_out_time, a.catid, a.created, a.created_by, a.created_by_alias,
CASE WHEN a.modified = '0000-00-00 00:00:00' THEN a.created ELSE a.modified END as modified, a.modified_by, uam.name as modified_by_name,
CASE WHEN a.publish_up = '0000-00-00 00:00:00' THEN a.created ELSE a.publish_up END as publish_up,a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured, LENGTH(a.fulltext) AS readmore,
CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state,c.title AS category_title, c.path AS category_route, c.access AS category_access, c.alias AS category_alias,
CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author,ua.email AS author_email,contact.id as contactid,parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias,ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count,c.published,
CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published
FROM mydatabase_content AS a
LEFT JOIN mydatabase_content_frontpage AS fp
ON fp.content_id = a.id
LEFT JOIN mydatabase_categories AS c
ON c.id = a.catid
LEFT JOIN mydatabase_users AS ua
ON ua.id = a.created_by
LEFT JOIN mydatabase_users AS uam
ON uam.id = a.modified_by
LEFT JOIN ( SELECT contact.user_id, MAX(contact.id) AS id, contact.language
FROM mydatabase_contact_details AS contact
WHERE contact.published = 1
GROUP BY contact.user_id, contact.language) AS contact
ON contact.user_id = a.created_by
LEFT JOIN mydatabase_categories as parent
ON parent.id = c.parent_id
LEFT JOIN mydatabase_content_rating AS v
ON a.id = v.content_id
LEFT
OUTER JOIN (SELECT cat.id as id
FROM mydatabase_categories AS cat JOIN mydatabase_categories AS parent
ON cat.lft BETWEEN parent.lft
AND parent.rgt
WHERE parent.extension = 'com_content'
AND parent.published != 1
GROUP BY cat.id ) AS badcats
ON badcats.id = c.id
WHERE a.access IN (1,1,5)
AND c.access IN (1,1,5)
AND
CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1
AND (a.catid = 164 OR a.catid IN ( SELECT sub.id
FROM mydatabase_categories as sub
INNER JOIN mydatabase_categories as this
ON sub.lft > this.lft
AND sub.rgt < this.rgt
WHERE this.id = 164))
AND (a.publish_up = '0000-00-00 00:00:00' OR a.publish_up <= '2013-08-07 07:00:01')
AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2013-08-07 07:00:01')
GROUP BY a.id, a.title, a.alias, a.introtext, a.checked_out, a.checked_out_time, a.catid, a.created, a.created_by, a.created_by_alias, a.created, a.modified, a.modified_by, uam.name, a.publish_up, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured, a.fulltext, a.state, a.publish_down, badcats.id, c.title, c.path, c.access, c.alias, uam.id, ua.name, ua.email, contact.id, parent.title, parent.id, parent.path, parent.alias, v.rating_sum, v.rating_count, c.published, c.lft, a.ordering, parent.lft, fp.ordering, c.id, a.images, a.urls
ORDER BY
CASE WHEN a.publish_up = '0000-00-00 00:00:00' THEN a.created ELSE a.publish_up END DESC , a.created
LIMIT 0, 7
---
SELECT a.id, a.title, a.alias, a.introtext, a.checked_out, a.checked_out_time, a.catid, a.created, a.created_by, a.created_by_alias,
CASE WHEN a.modified = '0000-00-00 00:00:00' THEN a.created ELSE a.modified END as modified, a.modified_by, uam.name as modified_by_name,
CASE WHEN a.publish_up = '0000-00-00 00:00:00' THEN a.created ELSE a.publish_up END as publish_up,a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured, LENGTH(a.fulltext) AS readmore,
CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state,c.title AS category_title, c.path AS category_route, c.access AS category_access, c.alias AS category_alias,
CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author,ua.email AS author_email,contact.id as contactid,parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias,ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count,c.published,
CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published
FROM mydatabase_content AS a
LEFT JOIN mydatabase_content_frontpage AS fp
ON fp.content_id = a.id
LEFT JOIN mydatabase_categories AS c
ON c.id = a.catid
LEFT JOIN mydatabase_users AS ua
ON ua.id = a.created_by
LEFT JOIN mydatabase_users AS uam
ON uam.id = a.modified_by
LEFT JOIN ( SELECT contact.user_id, MAX(contact.id) AS id, contact.language
FROM mydatabase_contact_details AS contact
WHERE contact.published = 1
GROUP BY contact.user_id, contact.language) AS contact
ON contact.user_id = a.created_by
LEFT JOIN mydatabase_categories as parent
ON parent.id = c.parent_id
LEFT JOIN mydatabase_content_rating AS v
ON a.id = v.content_id
LEFT
OUTER JOIN (SELECT cat.id as id
FROM mydatabase_categories AS cat JOIN mydatabase_categories AS parent
ON cat.lft BETWEEN parent.lft
AND parent.rgt
WHERE parent.extension = 'com_content'
AND parent.published != 1
GROUP BY cat.id ) AS badcats
ON badcats.id = c.id
WHERE a.access IN (1,1,5)
AND c.access IN (1,1,5)
AND
CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1
AND (a.catid = 164 OR a.catid IN ( SELECT sub.id
FROM mydatabase_categories as sub
INNER JOIN mydatabase_categories as this
ON sub.lft > this.lft
AND sub.rgt < this.rgt
WHERE this.id = 164))
AND (a.publish_up = '0000-00-00 00:00:00' OR a.publish_up <= '2013-08-07 07:00:01')
AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2013-08-07 07:00:01')
GROUP BY a.id, a.title, a.alias, a.introtext, a.checked_out, a.checked_out_time, a.catid, a.created, a.created_by, a.created_by_alias, a.created, a.modified, a.modified_by, uam.name, a.publish_up, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured, a.fulltext, a.state, a.publish_down, badcats.id, c.title, c.path, c.access, c.alias, uam.id, ua.name, ua.email, contact.id, parent.title, parent.id, parent.path, parent.alias, v.rating_sum, v.rating_count, c.published, c.lft, a.ordering, parent.lft, fp.ordering, c.id, a.images, a.urls
ORDER BY
CASE WHEN a.publish_up = '0000-00-00 00:00:00' THEN a.created ELSE a.publish_up END DESC , a.created
以下是第一个查询的EXPLAIN
:
第二个:
我的_content表有14,000多行,我知道在宏观方案中并不是那么多。
有没有人找到优化这种方法的好方法?我并不反对攻击核心(我知道他们不会这样做,但是如果你不能进入并摆弄它,那么开源项目的重点是什么?)如果这就是它所需要的。
所以,我发现this guy似乎正走在正确的道路上,所以我对它说地狱,然后尝试了。
在components / com_content / models / articles.php中,我替换了line 431
$query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')')
->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')');
与
$query->where('(a.publish_up >= DATE_SUB(NOW(), INTERVAL 1 YEAR))');
我知道这对每个人都不起作用,因为它可能会打破分页,但到目前为止似乎对我有用(我的模板使用js无限滚动解决方案而不是分页)。我想如果有人在寻找超过一年的文章,他们可以使用搜索功能。
这两个查询现在每个查询花费的时间少于0.04秒,而Joomla Debug的afterDispatch时间减少到1.469秒 - 不是最佳,但是我能忍受的数字并继续减少。
我知道这个解决方案非常hacky,可能不适合其他任何人,所以我很想听到有关改进/优化Joomla核心和Joomla股票查询的更多想法。
非常感谢!
答案 0 :(得分:1)
正如我在此处发布的那样:JOOMLA site too slow
我取消注释了
bind-address="127.0.0.1"
在MySQL配置文件(my.ini)中设置。
这使我在Windows 8.1上的本地Joomla安装的执行速度提高了。
答案 1 :(得分:0)
联系表上的联接和生成的group_by存在问题。 这已在使用https://github.com/joomla/joomla-cms/pull/1542的master中修复,我认为它应该已包含在当前版本中。 您使用的是哪个版本的Joomla?
答案 2 :(得分:-1)
我在windwos托管php + mysql时遇到了问题。将主机设置为IP地址。
host 127.0.0.1