1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Optimize vBulletin 4

Discussion in 'vBulletin' started by digitalpoint, Apr 13, 2010.

  1. #1
    Here's a few tips you can use to make large vBulletin forums faster and scale better (starting with the easiest stuff on down to the most difficult)... Please keep in mind that what works for me, may not work for you (so the obvious "do at your own risk" preface applies).

    Disable Memberlist
    There is an option to simply disable the memberlist under Settings -> Options -> User Listing Options.

    It might be missed at first, but ask yourself what the *real* purpose of it is... members can sort it to flex their e-peen to see who has the most posts, reputation or whatever else.

    Do people really use this to search for members? Probably not... when was the last time you used it to search for a member that you didn't already know who they were?

    In reality the main purpose of it is to give spammers an easy way to harvest your usernames so they can more easily blast out PM spams. On top of that, the queries required to generate the memberlist are terrible for your DB servers and can cause massive locking issues and DB server loads.

    Increase Private Message List Speed
    If you have never imported private messages from an external source (via ImpEx or anything else), you can safely rely on the pmid column to be in the same sort order as the PM date. Sorting on pmid will make it so your database server doesn't need to dump the PMs into a temporary table to perform the sort (making the query much faster).

    To do this, make a plug-in at the private_messagelist_filter hook location with the following line in it:
        if ($sortfield == 'pmtext.dateline') $sortfield = 'pm.pmid';
    PHP:
    You just made private.php ~20% faster.

    Find Last Post By User Efficiently
    In includes/class_userprofile.php, replace this:
    $getlastposts = $this->registry->db->query_read_slave("
        SELECT thread.title, thread.threadid, thread.forumid, thread.postuserid, post.postid, post.dateline
        FROM " . TABLE_PREFIX . "post AS post
        INNER JOIN " . TABLE_PREFIX . "thread AS thread USING (threadid)
        WHERE thread.visible = 1
            AND post.userid  = " . $this->userinfo['userid'] . "
            AND post.visible = 1
        ORDER BY post.dateline DESC
        LIMIT 20
    ");
    PHP:
    with this (just changes the ORDER BY):
    $getlastposts = $this->registry->db->query_read_slave("
        SELECT thread.title, thread.threadid, thread.forumid, thread.postuserid, post.postid, post.dateline
        FROM " . TABLE_PREFIX . "post AS post
        INNER JOIN " . TABLE_PREFIX . "thread AS thread USING (threadid)
        WHERE thread.visible = 1
            AND post.userid  = " . $this->userinfo['userid'] . "
            AND post.visible = 1
        ORDER BY post.postid DESC
        LIMIT 20
    ");
    PHP:
    This makes the query be able to hit indexes properly and not need to do a filesort on a temporary table. For users with a ton of posts, the original query can take 10+ seconds, but it becomes instant when fixing the ORDER BY. This is primarily used on the member profile page to display the last post the user posted in.

    Check Thread Indexes
    If any of your forums have a default sort order that is set to anything other than Last Post Time, make an index for it in your thread table.

    We have some forums that the default sort order is the thread creation time (the column used for that is "dateline"), so we created the following index:
    ALTER TABLE thread ADD INDEX forumid2_dp (forumid, visible, sticky, dateline)
    Code (markup):
    Be Very Careful What Add-Ons You Install
    Just because someone makes an add-on, it does not mean it was made with a large forum in mind. A perfect example is the iTrader system. We use it here, but only after we made MANY changes to it so that it has the ability to scale.

    It's best to assume add-on developers don't know what they are doing and go over all their code before you go live with something. Make sure the add-ons aren't causing database load issues, make sure they don't have potential SQL injection issues or XSS issues. Unfortunately with thousands of add-ons out there, you will just have to do this yourself (or hire someone to do it). And it's also the reason we went the route of just writing all our own plug-ins for the most part vs. building on something that might be bad to begin with. (Yes, I know I have trust issues. heh)

    Replace Search
    For this site, I developed a Sphinx-based search replacement for the normal vBulletin search that is freely available to premium members over here.

    Using this is probably the single best thing you can do for your database servers.

    Don't Use InnoDB Tables (maybe)
    This is a heavy subject for argument, but for us it's worked well. We use 100% MyISAM tables for everything (and we are processing more than 1,000 queries per second).

    If you get to the point where you are not having any table/record locking issues (most notably after you replace vBulletin search), change vBulletin's InnoDB tables to MyISAM. MyISAM is faster for individual queries (since it doesn't need to manage record locks among other things). InnoDB can be faster overall, but only because it allows you to run queries concurrently. If your queries run so fast under MyISAM that they don't even *need* to run concurrently, there is no point to run InnoDB.

    In my opinion the best solution to slow database queries is to fix the query itself so it's not slow. Just converting the table to InnoDB is a lazy way to fix it because all you are doing is making it okay for other queries to run while the slow query is running.

    Update: MySQL has come a long way with InnoDB, and I'd say starting with MySQL 5.5, it's a better option in most cases than MyISAM. If your DB server uses MySQL 5.5 or higher, using InnoDB tables may be a good option for you.

    Clean Up Cache - No longer needed with vBulletin 4.1.8+: see this page for more info.
    vBulletin 4 has an internal database based cache that never cleans itself up (don't ask me why). Expired cache items will stay in the database indefinitely (until you purge the entire cache).

    Create a plug-in at the cron_script_cleanup_hourly location with the following PHP code and cache items that are expired/unused will be purged hourly:
    require_once(DIR . '/includes/class_bootstrap_framework.php');
    vB_Bootstrap_Framework::init();
    vB_Cache::instance()->clean(true);
    PHP:
    Drop FULLTEXT Indexes - No longer needed with vBulletin 4.1.7+: see this page for more info.
    If you upgraded from vBulletin 3, you can drop every FULLTEXT index in your database EXCEPT for the ones in searchcore_text and searchgroup_text. The vBulletin 4 upgrade process does not remove the old vBulletin 3 FULLTEXT indexes that are no longer used. By default there are 4 of these indexes (in the post, groupmessage, socialgroup and thread tables) which can be removed.

    Update: The 4.0.4 update removes all of these indexes automatically EXCEPT for the thread index.

    showgroups.php Query Cache - No longer needed with vBulletin 4.1.5+: see this page for more info.
    There is a query in showgroups.php that does not scale (it will get slower and slower the more users you have).
    A quick fix is to just cache the query results for 6 hours (so it's not run more than once every 6 hours) like so...
    Change this:
    
    // get usergroups who should be displayed on showgroups
    // Scans too many rows. Usergroup Rows * User Rows
    $users = $db->query_read_slave("
    SELECT user.*,
      usergroup.usergroupid, usergroup.title,
      user.options, usertextfield.buddylist,
      " . ($show['locationfield'] ? 'userfield.field2,' : '') . "
      IF(user.displaygroupid = 0, user.usergroupid, user.displaygroupid) AS displaygroupid
      " . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight, customavatar.width_thumb AS avwidth_thumb, customavatar.height_thumb AS avheight_thumb, filedata_thumb, NOT ISNULL(customavatar.userid) AS hascustom" : "") . "
    FROM " . TABLE_PREFIX . "user AS user
    LEFT JOIN " . TABLE_PREFIX . "usergroup AS usergroup ON(usergroup.usergroupid = user.usergroupid OR FIND_IN_SET(usergroup.usergroupid, user.membergroupids))
    LEFT JOIN " . TABLE_PREFIX . "userfield AS userfield ON(userfield.userid = user.userid)
    LEFT JOIN " . TABLE_PREFIX . "usertextfield AS usertextfield ON(usertextfield.userid=user.userid)
    " . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
    WHERE (usergroup.genericoptions & " . $vbulletin->bf_ugp_genericoptions['showgroup'] . ")
    ");
    $groupcache = array();
    while ($user = $db->fetch_array($users))
    {
    $t = strtoupper($user['title']);
    $u = strtoupper($user['username']);
    $groupcache["$t"]["$u"] = $user;
    }
    
    PHP:
    to this (really just wrapped the vb_Cache class mechanism around the query and $groupcache generation):
    
    
    
    require_once(DIR . '/includes/class_bootstrap_framework.php');
    vB_Bootstrap_Framework::init();
    if (!$groupcache = vB_Cache::instance()->read('showgroups.groupcache')) {
    
    // get usergroups who should be displayed on showgroups
    // Scans too many rows. Usergroup Rows * User Rows
    $users = $db->query_read_slave("
      SELECT user.*,
       usergroup.usergroupid, usergroup.title,
       user.options, usertextfield.buddylist,
       " . ($show['locationfield'] ? 'userfield.field2,' : '') . "
       IF(user.displaygroupid = 0, user.usergroupid, user.displaygroupid) AS displaygroupid
       " . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight, customavatar.width_thumb AS avwidth_thumb, customavatar.height_thumb AS avheight_thumb, filedata_thumb, NOT ISNULL(customavatar.userid) AS hascustom" : "") . "
      FROM " . TABLE_PREFIX . "user AS user
      LEFT JOIN " . TABLE_PREFIX . "usergroup AS usergroup ON(usergroup.usergroupid = user.usergroupid OR FIND_IN_SET(usergroup.usergroupid, user.membergroupids))
      LEFT JOIN " . TABLE_PREFIX . "userfield AS userfield ON(userfield.userid = user.userid)
      LEFT JOIN " . TABLE_PREFIX . "usertextfield AS usertextfield ON(usertextfield.userid=user.userid)
      " . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
      WHERE (usergroup.genericoptions & " . $vbulletin->bf_ugp_genericoptions['showgroup'] . ")
    ");
    
    $groupcache = array();
    while ($user = $db->fetch_array($users))
    {
      $t = strtoupper($user['title']);
      $u = strtoupper($user['username']);
      $groupcache["$t"]["$u"] = $user;
    }
    
    vB_Cache::instance()->write('showgroups.groupcache', $groupcache, 360);
    }
    
    
    
    PHP:
    For us, it makes the showgroups.php page load 6x faster.
    Gross Query In editpost.php - No longer needed with vBulletin 4.1.4+: see this page for more info.
    When a user edits a post, vBulletin does a query to see if that is the first post in the thread (in case the title needs to change). For whatever reason, MySQL doesn't use the most efficient index if the thread has a ton of posts (we would see the query to determine the first post of a thread take over 60 seconds in some cases... which means someone edits a post, and it would be more than a minute before they would get the edit page). The thing about it is we already know the first post ID, because vBulletin stores it with the thread info for all threads, so the query is 100% redundant and unnecessary.

    In editpost.php, change this:
        // find out if first post
    $getpost = $db->query_first("
        SELECT postid
        FROM " . TABLE_PREFIX . "post
        WHERE threadid = $threadinfo[threadid]
        ORDER BY dateline
        LIMIT 1
    ");
    if ($getpost['postid'] == $postinfo['postid'])
    {
        $isfirstpost = true;
    }
    else
    {
        $isfirstpost = false;
    }
    PHP:
    to this:
    $isfirstpost = $postinfo['postid'] == $threadinfo['firstpostid'] ? true : false;
    PHP:
    You get the exact same info, without needing to make a query of any kind.

    Fix Memory Usage On member.php and online.php - No longer needed with vBulletin 4.1.4+: see this page for more info.
    There is a malformed query in vBulletin that causes it to get and loop through every user record in the system if the last action of a member was viewing posts by a certain user.

    In includes/functions_online.php, within the convert_ids_to_titles() function, replace this:
    $userids .= ",userid";
    PHP:
    with this:
    $userids .= ",$targetuserid";
    PHP:
    For us it made PHP go from taking 400MB and 60 seconds to render the page down to 7MB and 0.1 seconds.

    Use YUI 2.9.x - No longer needed with vBulletin 4.1.4+: see this page for more info.
    vBulletin 4.x currently ships with an outdated version of Yahoo User Interface (version 2.7.0). You can simply replace 2.7.0 with 2.9.x without any problems (2.8.x has a number of bug fixes, and so does 2.9.x).

    The easiest way to do this is to go to Settings -> Options -> Server Settings and Optimization Options and make sure your Use Remote YUI setting is set to use Yahoo or Google remote hosting. Then edit your includes/class_core.php file and change this line:
    define('YUI_VERSION', '2.7.0'); // define the YUI version we bundle
    PHP:
    to this:
    define('YUI_VERSION', '2.9.0'); // define the YUI version we bundle
    PHP:
    Disable Quick Nav- No longer needed with vBulletin 4.1.3+: see this page for more info.
    I found that 20-30% of the global/init functions of the vBulletin framework were spent generating the quicknav HTML. For something that is hardly used, it seemed like a lot of overhead. You can disable it under AdminCP -> Settings -> Options -> General Settings -> Use Quick Navigation Menu

    Setting SQL Mode - No longer needed with vBulletin 4.1.3+: see this page for more info.
    A blank sql_mode is the default setting for MySQL, so unless you've overridden your MySQL server to have a specific sql_mode, just comment the following line within includes/init.php (all it does is make sure sql_mode is set to the default value):
    $db->force_sql_mode('');
    PHP:
    like so:
    // $db->force_sql_mode('');
    PHP:
    The query doesn't take long to run, but it is a query to the DB server nonetheless. One less query per page view is always a good thing.

    Using Memcache Datastore More Efficiently - No longer needed with vBulletin 4.1.3+: see this page for more info.
    If you use Memcache as your datastore, you can make it faster by getting multiple datastore keys in a single pass (Memcache supports it, why not use it?).

    In includes/class_datastore.php, within the vB_Datastore_Memcached::fetch() method, replace this:
    $unfetched_items = array();
    foreach ($items AS $item)
    {
        $this->do_fetch($item, $unfetched_items);
    }
    PHP:
    with this:
    if ($this->prefix) {
        foreach ($items as $item) {
            $items_fetch[] = $this->prefix . $item;
        }
    }
    else
    {
        $items_fetch =& $items;
    }
           
    $items_found = $this->memcache->get($items_fetch);
    $unfetched_items = array_keys(array_diff_key(array_flip($items_fetch), $items_found));
    foreach ($items_found AS $key => $data)
    {
        $this->register(substr($key, strlen($this->prefix), 50), $data);
    }
    PHP:
    This will make getting your datastore (needed for every page view) about 20% faster. Memcache is very fast either way, so you probably won't notice much of a difference, but there's no point in *not* making something faster when you can in my opinion.

    Generate Currently Active Users More Efficiently - No longer needed with vBulletin 4.1.2+: see this page for more info.
    The "Currently Active Users" list that appears on the forum home page spins every user through the whole template rending engine, which requires registering a bunch of global variables for each user. It's much more efficient to make use of vBulletin 4's {vb:each} tag and just loop through them from the main template.

    In forum.php change this:
    $show['comma_leader'] = ($activeusers != '');
    $templater = vB_Template::create('forumhome_loggedinuser');
        $templater->register('loggedin', $loggedin);
    $activeusers .= $templater->render();
    PHP:
    to this:
    $activeusers[] = $loggedin;
    PHP:
    Then in the FORUMHOME template, change this:
    {vb:raw activeusers}
    Code (markup):
    to this:
    <vb:each from="activeusers" value="loggedin">
        <li> {vb:stylevar dirmark}<a class="username" href="{vb:link member, {vb:raw loggedin}}">{vb:raw loggedin.musername}</a>{vb:raw loggedin.invisiblemark}{vb:raw loggedin.buddymark}</li>
    </vb:each>
    Code (markup):
    If you have 500 logged in users, it saves around 7,500 sub-routine calls for registering variables and the net effect is your home page loads about twice as fast.


    Fix Cache Table Structure - No longer needed with vBulletin 4.1.1+: see this page for more info.
    The internal cache system does not allocate enough space to store large cached items (large articles for example). Change the data column within the cache table to be a MEDIUMBLOB instead of a BLOB with the following SQL command:
    ALTER TABLE cache CHANGE data data MEDIUMBLOB NULL DEFAULT NULL
    Code (markup):
    Slow Social Groups Query - No longer needed with vBulletin 4.0.8+: see this page for more info.
    Within includes/functions_socialgroup.php (at the end) there is a query with a clever (but VERY inefficient sub-query). This change makes the social groups page in this forum render in 0.17 seconds instead of 1.2 seconds (7 times faster). There are many good times to use sub-queries (for example in the above example in forumdisplay.php). This query is not one of them.

    Change this:
        $result = $vbulletin->db->query_read_slave("
            SELECT user.*, socialgroupmember.groupid
                " . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight" : "") . "
            FROM " . TABLE_PREFIX . "socialgroupmember AS socialgroupmember
            LEFT JOIN " . TABLE_PREFIX . "user AS user ON (socialgroupmember.userid = user.userid)
            " . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
            WHERE socialgroupmember.groupid IN (" . implode(',', $groupids) . ")
            AND 10 > (
                SELECT COUNT( * )
                FROM " . TABLE_PREFIX . "socialgroupmember AS socialgroupmember2
                WHERE socialgroupmember2.groupid = socialgroupmember.groupid
                AND socialgroupmember2.dateline > socialgroupmember.dateline
                AND socialgroupmember2.type = 'member'
            )
            ORDER BY socialgroupmember.dateline DESC
        ");
    
        $group_members = array();
        while ($member = $vbulletin->db->fetch_array($result))
        {
            fetch_avatar_from_userinfo($member, true, true);
            $group_members[$member['groupid']][] = $member;
        }
    PHP:
    to this:
    $group_members = array();
    foreach ($groupids AS $groupid) {
        $result = $vbulletin->db->query_read_slave("
            SELECT user.*, socialgroupmember.groupid
                " . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight" : "") . "
            FROM " . TABLE_PREFIX . "socialgroupmember AS socialgroupmember
            LEFT JOIN " . TABLE_PREFIX . "user AS user ON (socialgroupmember.userid = user.userid)
            " . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
            WHERE socialgroupmember.groupid = $groupid
                AND socialgroupmember.type = 'member'
            ORDER BY socialgroupmember.dateline DESC
            LIMIT 10
        ");
        while ($member = $vbulletin->db->fetch_array($result))
        {
            fetch_avatar_from_userinfo($member, true, true);
            $group_members[$member['groupid']][] = $member;
        }
    }
    PHP:
    Alter post.userid Index - No longer needed with vBulletin 4.0.8+: see this page for more info.
    There is a query that vBForum_Search_Result_Post::set_replydata() uses that searches the post table by userid and parentid. There is no index that includes both columns, so if the user has a lot of posts in your forum, this query can be terribly slow.

    If you simply add the parentid column to the existing userid index the query will be lightning fast.
    ALTER TABLE post DROP INDEX userid, ADD INDEX userid (userid, parentid)
    Code (markup):
    Nasty Query In forumdisplay.php - No longer needed with vBulletin 4.0.8+: see this page for more info.
    In vBulletin 4, the minimum required MySQL version is 4.1.0. This means we can start utilizing sub-queries where appropriate (or just more efficient in this case).

    forumdisplay.php is one of the most trafficked pages in vBulletin, so anything we can do to make this page more efficient is definitely worth the effort.

    I suggested it to the vBulletin developers years ago back in version 3.7.x, but nothing ever was done to fix it. Hopefully someday this change will be incorporated into the source of vBulletin 4.

    In forumdisplay.php, change this query:
        # Include visible IN (0,1,2) in order to hit upon the 4 column index
        $threadscount = $db->query_first_slave("
            SELECT COUNT(*) AS threads, SUM(IF(thread.lastpost > $lastread AND open <> 10, 1, 0)) AS newthread
            $hook_query_fields
            FROM " . TABLE_PREFIX . "thread AS thread
            $tachyjoin
            $hook_query_joins
            WHERE forumid = $foruminfo[forumid]
                AND sticky = 0
                $prefix_filter
                $visiblethreads
                $globalignore
                $limitothers
                $datecut
                $hook_query_where
        ");
    PHP:
    to this:
        # Include visible IN (0,1,2) in order to hit upon the 4 column index
        $threadscount = $db->query_first_slave("
            SELECT COUNT(*) AS threads,        
            (
                SELECT COUNT(*) AS newthread
                FROM " . TABLE_PREFIX . "thread AS thread
                WHERE forumid = $foruminfo[forumid]
                    AND lastpost > $lastread
                    AND open <> 10
                    AND sticky = 0
                    $prefix_filter
                    $visiblethreads
                    $globalignore
                    $limitothers
                    $datecut
                    $hook_query_where
            ) AS newthread
            $hook_query_fields
            FROM " . TABLE_PREFIX . "thread AS thread
            $tachyjoin
            $hook_query_joins
            WHERE forumid = $foruminfo[forumid]
                AND sticky = 0
                $prefix_filter
                $visiblethreads
                $globalignore
                $limitothers
                $datecut
                $hook_query_where
        ");
    PHP:
    The new query yields the exact same results, but does so with a sub-query instead of a terribly slow SUM(IF()) statement that is unable to hit an index.

    Look at the time to run the default query:
    +---------+-----------+
    | threads | newthread |
    +---------+-----------+
    |   96484 |      2051 |
    +---------+-----------+
    1 row in set (0.49 sec)
    Code (markup):
    ...and compare it to the time needed to run the new query:
    +---------+-----------+
    | threads | newthread |
    +---------+-----------+
    |   96484 |      2051 |
    +---------+-----------+
    1 row in set (0.01 sec)
    Code (markup):
    We just made one of the main queries in forumdisplay.php 50x faster.

    Yucky functions_newpost.php Query - No longer needed with vBulletin 4.0.7+: see this page for more info.
    When a user makes a post, vBulletin checks what the first postid is within the thread they are posting in. It's a resource intensive query that does not scale (the larger the thread, the slower it gets). The dumb thing is we already *have* the information we need without doing a query.

    In functions_newpost.php, change this:
    $getfirstpost = $vbulletin->db->query_first("SELECT postid FROM " . TABLE_PREFIX . "post WHERE threadid=$threadinfo[threadid] ORDER BY dateline LIMIT 1");
    $parentid = $getfirstpost['postid'];
    PHP:
    to this:
    $parentid = $threadinfo['firstpostid'];
    PHP:
    CMS Article Caching - No longer needed with vBulletin 4.0.4+: see this page for more info.
    CMS articles are completely run through the BBCode parser for every page view and it takes a painful amount of time to do so (this is the main reason the vBulletin CMS is so slow).

    In packages/vbcms/content/article.php, change this:
       
            $view->pagetext = fetch_censored_text($bbcode_parser->do_parse(
                     $this->content->getPageText(),
                     vBCMS_Permissions::canUseHtml($this->getNodeId(), $this->content->getContentTypeId(), $this->content->getUserId()),
                     $this->content->getHtmlState()
                 ));
    PHP:
    to this:
    $md5_key = 'article.' . md5($this->content->getPageText());
    if (!$view->pagetext = vB_Cache::instance()->read($md5_key)) {
                $view->pagetext = fetch_censored_text($bbcode_parser->do_parse(
                     $this->content->getPageText(),
                     vBCMS_Permissions::canUseHtml($this->getNodeId(), $this->content->getContentTypeId(), $this->content->getUserId()),
                     $this->content->getHtmlState()
                 ));
        vB_Cache::instance()->write($md5_key, $view->pagetext, 360);
    }
    PHP:
    This will make the parsing of your articles only need to do so no more often than once every 6 hours (or if you edit the article). This small change made our vBulletin CMS render pages 8.5x faster (no joke).
     
    digitalpoint, Apr 13, 2010 IP
    EvoWRZ® and Karen May Jones like this.
  2. Brandon Sheley

    Brandon Sheley Illustrious Member

    Messages:
    9,721
    Likes Received:
    612
    Best Answers:
    2
    Trophy Points:
    420
    #2
    thanks!
    bookmarking this
     
    Brandon Sheley, Apr 15, 2010 IP
  3. proxywhereabouts

    proxywhereabouts Notable Member

    Messages:
    4,027
    Likes Received:
    110
    Best Answers:
    0
    Trophy Points:
    200
    #3
    Hey Shawn, the code you suggested, any revision about it for vb4? Searched in forumdisplay.php but didn't find it.
     
    proxywhereabouts, Apr 16, 2010 IP
  4. digitalpoint

    digitalpoint Overlord of no one Staff

    Messages:
    38,333
    Likes Received:
    2,613
    Best Answers:
    462
    Trophy Points:
    710
    Digital Goods:
    29
    #4
    No, that should be it (for vB4). If you are specifically searching for the part with the SQL query, just search for a smaller part of the string... maybe your text editor doesn't like searching across line breaks. For example, just search for "Include visible IN (0,1,2) in order to hit upon the 4 column index" or something.
     
    digitalpoint, Apr 16, 2010 IP
  5. proxywhereabouts

    proxywhereabouts Notable Member

    Messages:
    4,027
    Likes Received:
    110
    Best Answers:
    0
    Trophy Points:
    200
    #5
    Yeah, I did that. Went into style manager, used the search in template option for "Include visible IN" but it just returned "not found".
    Use the firefox search function as well (ctrl+f) but no luck as well. (although I tried keyword" javascript" and it shows just find.
    vb 4.0.2 forum.

    Haha...I even copied the whole forumdisplay code into notepad++ and use the search function to look for "Include visible IN (0,1,2)" and still didn't find any.
     
    proxywhereabouts, Apr 16, 2010 IP
  6. digitalpoint

    digitalpoint Overlord of no one Staff

    Messages:
    38,333
    Likes Received:
    2,613
    Best Answers:
    462
    Trophy Points:
    710
    Digital Goods:
    29
    #6
    It's a raw PHP file, not a template.
     
    digitalpoint, Apr 16, 2010 IP
  7. Ruddo

    Ruddo Member

    Messages:
    821
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    43
    #7
    Thanks for sharing these tips :)
     
    Ruddo, Apr 16, 2010 IP
  8. craig105

    craig105 Well-Known Member

    Messages:
    877
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    138
    #8
    Thanks I'm going to implement some of this into my forum soon.
     
    craig105, Apr 18, 2010 IP
  9. Peter_Rosado

    Peter_Rosado Active Member

    Messages:
    544
    Likes Received:
    18
    Best Answers:
    0
    Trophy Points:
    58
    #9
    Great tips =) I implemented them and have had great results. If only VB would listen... :rolleyes:
     
    Peter_Rosado, Apr 20, 2010 IP
    Karen May Jones likes this.
  10. superfrankie

    superfrankie Well-Known Member

    Messages:
    1,164
    Likes Received:
    16
    Best Answers:
    0
    Trophy Points:
    180
    #10
    @ Shawn

    Whats the reason of not using local vBSearch, The results aren't relevant correct? I had same problems, using Google Search at the moment.

    While I am thinking to try removing that nasty query.
     
    superfrankie, Apr 20, 2010 IP
  11. digitalpoint

    digitalpoint Overlord of no one Staff

    Messages:
    38,333
    Likes Received:
    2,613
    Best Answers:
    462
    Trophy Points:
    710
    Digital Goods:
    29
    #11
    It's not so much about relevancy as it is about the time it takes to actually run the SQL query to *do* the search. If you have a large forum, simple searches can take minutes to run... in itself it wouldn't be THAT bad if it only affected the person doing the search... but a search that takes minutes locks the tables and other people doing things in your forum will have to wait for the search to finish before they can do something (like post a new thread).

    The larger the forum, the more problematic it becomes.
     
    digitalpoint, Apr 20, 2010 IP
  12. superfrankie

    superfrankie Well-Known Member

    Messages:
    1,164
    Likes Received:
    16
    Best Answers:
    0
    Trophy Points:
    180
    #12
    I agree with, You The reason i removed it had, some Tag Association problem., I wonder if this can be integrated http://www.sphider.eu/. Apart from that I removed that Nasty Query, forumdisplay.php is really fast now and changed YUI version too.
    :cool: thanks shawn
     
    superfrankie, Apr 21, 2010 IP
  13. miau

    miau Peon

    Messages:
    25
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #13
    I found great tips here :)
     
    miau, Apr 21, 2010 IP
  14. punchbowl

    punchbowl Greenhorn

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    11
    #14
    fantastic! Saves me stalking dp around the bug tracker for these gems:D
     
    punchbowl, Apr 22, 2010 IP
  15. phpscriptsonline4u

    phpscriptsonline4u Peon

    Messages:
    3
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #15
    thanks!
    for news information bookmarking this
     
    phpscriptsonline4u, Apr 23, 2010 IP
  16. RaceDirector

    RaceDirector Active Member

    Messages:
    122
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    70
    #16
    Shawn

    After the changes to the .php files, do you recommend setting them as "read only" to prevent any upgrades overwriting them?
     
    RaceDirector, Apr 24, 2010 IP
  17. digitalpoint

    digitalpoint Overlord of no one Staff

    Messages:
    38,333
    Likes Received:
    2,613
    Best Answers:
    462
    Trophy Points:
    710
    Digital Goods:
    29
    #17
    Nah... other parts of the files may change in new versions, so...
     
    digitalpoint, Apr 25, 2010 IP
  18. RaceDirector

    RaceDirector Active Member

    Messages:
    122
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    70
    #18
    Thats cool, filemerge is your friend :)
     
    RaceDirector, Apr 25, 2010 IP
  19. gizah

    gizah Member

    Messages:
    57
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    41
    #19
    Are any of these changes likely to be affected by the new development planned for VB4.0.4 or they can be implemented straight away.
    I am still having trouble with lots of small things like having a proper xml sitemap for VB4.
    Any ideas to ad onto this?
    Thanks
     
    gizah, Apr 28, 2010 IP
  20. buy-host

    buy-host Active Member

    Messages:
    40
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    61
    #20
    disabling the Members List is bad if you use Group Memberships.. you can't List the Members in that usergroup, and then you can't remove them from that usergroup through the Group Memberships page in the usercp.

    So keep that in mind if you use Group Memberships on your site.
     
    buy-host, Apr 30, 2010 IP