大量のコンテンツでのJoomlaのパフォーマンス

画像



Joomlaは、_contentテーブルに数千の記事がある場合でも、データベースのダイジェストが非常に不十分です。 数万の場合、mod_articles_popularタイプの標準モジュールのデータベースへのリクエストは数秒間フリーズする場合があります。



ACL(アクセス制御リスト)-アクセス制御ポリシーがすべてです。 マテリアルへのユーザーアクセスの合法性の確認には、クエリ時間の98%以上がかかります。



一方、これを必要としないサイトがあります。 たとえば、左の列に「最も読まれた記事」モジュールを全員に表示するニュースサイト。 この場合の対処方法 helper.phpモジュールでACLチェックを無効にします。 幸いなことに、これは難しくありません-行にコメントしてください:



$model->setState('filter.access', $access);
      
      





結果を見てみましょう。 管理パネルでデバッグを有効にし、このモジュールのデータベースへのリクエストのデバッグ情報を調べます。 ここにACLがありません:



ACLなしのmod_articles_popular dbへのリクエスト
  : 18.84 ms   : 6.38 ms  : 0.012 MB   : 7.288 MB  : 5 SELECT a.id, a.title, a.alias, a.introtext, a.fulltext, 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, a.language, 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,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 jos_content AS a LEFT JOIN jos_categories AS c ON c.id = a.catid LEFT JOIN jos_users AS ua ON ua.id = a.created_by LEFT JOIN jos_users AS uam ON uam.id = a.modified_by LEFT JOIN jos_categories as parent ON parent.id = c.parent_id LEFT JOIN jos_content_rating AS v ON a.id = v.content_id LEFT OUTER JOIN (SELECT cat.id as id FROM jos_categories AS cat JOIN jos_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 CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1 AND a.catid IN (9,11,12,13,15,21,24,25) AND a.publish_up >= DATE_SUB('2018-04-30 03:27:24', INTERVAL 60 DAY) ORDER BY a.hits DESC LIMIT 5
      
      







ここにACLがあります:



ACLを使用したmod_articles_popular dbへのリクエスト
  : 972.79 ms   : 3.96 ms  : 0.012 MB   : 7.378 MB  : 5 SELECT a.id, a.title, a.alias, a.introtext, a.fulltext, 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, a.language, 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,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 jos_content AS a LEFT JOIN jos_categories AS c ON c.id = a.catid LEFT JOIN jos_users AS ua ON ua.id = a.created_by LEFT JOIN jos_users AS uam ON uam.id = a.modified_by LEFT JOIN jos_categories as parent ON parent.id = c.parent_id LEFT JOIN jos_content_rating AS v ON a.id = v.content_id LEFT OUTER JOIN (SELECT cat.id as id FROM jos_categories AS cat JOIN jos_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,2,3,6) AND c.access IN (1,1,2,3,6) AND CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1 AND a.catid IN (9,11,12,13,15,21,24,25) AND a.publish_up >= DATE_SUB('2018-04-30 03:36:50', INTERVAL 60 DAY) ORDER BY a.hits DESC LIMIT 5
      
      







違いは、WHERE句の2つのチェックのみです。



 a.access IN (1,1,2,3,6) AND c.access IN (1,1,2,3,6)
      
      





最初の行のクエリ実行時間:19ミリ秒と973ミリ秒。 98% 5,000件の記事のデータベースに基づいています。 強力なホストサーバー上。 これは、広く公開されているJoomla ACLの価格です。



しかし、このフレームワークの開発者はこの瞬間をよく知っており、管理パネルにACLチェックを無効にする機能を組み込んでいることがわかりました。 しかし、彼らは誰も推測しないようにそれをしました。



このオプションは、「一般設定」->「素材」の最初のタブ「素材」の下部にあり、「不正なリンクを表示」と呼ばれます。 ポップアッププロンプトによって解読されます:「 はいに設定すると、承認されていないユーザーを含むすべてのユーザーが資料の全文を表示するリンクを表示できますが、全文を表示するにはユーザー名とパスワードを入力する必要があります 。」



関係ないように見えますが、まさに必要なことを行います-すべてのモジュール(このポリシーを使用する)のACLチェックをキャンセルします。 $ model-> setState( 'filter.access'、$ access)の$ access変数は、このチェックボックスです(逆/感嘆符付き)。 この存在は、このCMSの開発者の1人によって示唆されました。



必要な人はジュムラを復活させることができます。



注:コメントでのテストと議論から判明したように、ACL検証によるこのリクエストでのこのようなブレーキングは不規則に発生し、決定論的ではありません。 私のテストで大量のデータに対してディスク操作を使用する条件で計算フィールドを持つインデックスのないサンプルは、DBMSメモリに収まらない場合があり、場合によっては収まる場合があります。この場合、ACLを使用した上記のリクエストは約50%長くなりました。 おそらくこれはサーバー環境に依存します。



All Articles