It is currently Sat Jul 04, 2009 5:22 am (All times are UTC )

 




Post new topic Reply to topic  [ 13 posts ] 
Author Message
Posted: Thu Apr 12, 2007 11:08 pm 
User avatar
Joomla! Guru
Joomla! Guru
Offline

Joined: Thu Aug 18, 2005 8:53 am
Posts: 700
Location: Switzerland
Hi Guys,

Here a small contribution to Joomla 1.5 SQL performances, taken from optimizations on 3 high-traffic (>50k users, sometimes >1k users logged-in same time) websites.

Took many days of work, partly paid by customers agreeing to share the results with the Community 8) (and for Query 2 and 3 optimization proposals, they come from a famous MySQL performance experts team  :P ). Acknowledgements will follow if wished by the clients.  ;)

These optimizations have been done and benchmarked + tested on all 3 high-traffic websites in Joomla 1.0.12, so they are pretty safe to be included for 1.5 beta 2, if you wish to do so, as Joomla's 1.0 database structure is frozen and Joomla 1.5 is the (near) future.

Hope it makes it into 1.5 beta 2...

Best Regards.
Beat

------------------------------------------------------------

Query 1.

Query: SELECT g.* FROM jos_core_acl_aro_groups AS g
  INNER JOIN jos_core_acl_groups_aro_map AS gm ON gm.group_id = g.group_id
  INNER JOIN jos_core_acl_aro AS ao ON ao.aro_id = gm.aro_id
WHERE ao.value='20608';

Issue: there are no suitable indexes which would be selective enough
and this query causes a full scan.

Solution: an appropriate index needs to be created on this table.

ALTER TABLE `jos_core_acl_aro` ADD UNIQUE INDEX `value` ( `value` );

ALTER TABLE `jos_core_acl_groups_aro_map` ADD INDEX `aro_id` ( `aro_id` );


*******************************************************************************
Query 2.

Stats: ~2200 times/day, ~90K rows/query, ~0.3 sec/query

Query: select gr.group_id
from jos_core_acl_groups_aro_map as gr
left join jos_core_acl_aro as aro on aro.aro_id = gr.aro_id
where value=21587;

Issue: "value" column is VARCHAR(240) and 21587 is integer which prevents
MySQL from using an index.

Solution: either key value should either be taken in quotes, ie:

... where value='21587';

or the column should be converted to INTEGER type if it only contains
integer data.

We chose to convert it to INTEGER to check it works fine (indeed, as it's anyway used as such ;) ). Also the index might be smaller and faster with INTEGER than with VARCHAR.


------------------------------------------------------------
Query 3.

Stats: ~400 times/day, ~45K rows/query

Query: SELECT id  FROM jos_users  WHERE email = 'ken@example.com'  AND id != 13727;

Issue: there is no index on "email" column and full scan is performed.

Solution: create an index on "email" column.

CREATE INDEX idxemail ON jos_users ( email );


*******************************************************************

Query 4:

SELECT a.id, a.title, a.hits, a.created
FROM jos_content AS a
WHERE a.created_by = 1639
AND a.state = 1
AND a.sectionid=4
ORDER BY a.created DESC
LIMIT 0,10

Problem: full table scan.

Solution: add appropriate index:

ALTER TABLE `jos_content` ADD INDEX `idx_created_by` ( `created_by` )


********************************************************************

Query 5:

SELECT ....
LEFT JOIN u.username FROM jos_users u ON u.id = c.id
WHERE u.block = 0;

Problem: full table scan...

Solution: add index (and drop an unused one):

ALTER TABLE `jos_users` DROP INDEX `block_regdate`;
ALTER TABLE `mos_users` ADD INDEX `block_id` ( `block` , `id` );



**************************************************************

Query 6: on login: search in jos_users on username

Problem: makes a full table search, since username is not indexed.

Solution: create index:

ALTER TABLE `jos_users` ADD INDEX `username` ( `username` );


****************************************************************

Query 7:

find session of user in jos_sessions to see if user is logged-in (e.g. in users online module):

Problem: search on user_id does full scan, as it's not indexed.

Solution: create index:

ALTER TABLE `jos_session` ADD INDEX `userid` ( `userid` );


********************************************************

Query 8:

Problem:
Duplicate indexes are bad since mysql sometimes (often) gets fooled and misses to use the right one, leading to way slower queries than without indexes at all !!!

e.g. jos_categories:

idx_section: section
cat_idx: section - published - access

idx_section is redundant (you can point phpMyAdmin to jos_category of Joomla 1.5 svn and see the yellow warning).

why is it redundant ?

mysql is clever enough to use cat_idx when it needs an index on section column, ignoring the rest of the index.

Solution: Remove the redundant index with the smallest amount of fields:

ALTER TABLE `jos_categories` DROP INDEX `idx_section`;



*******************************************************************************

Query 9:

Same Problem in jos_core_acl_aro_sections:

value_aro_sections : UNIQUE: value
jos_gacl_value_aro_sections : UNIQUE: value
hidden_aro_sections: hidden
jos_gacl_hidden_aro_sections: hidden

Solution: remove 2 of them: e.g.
ALTER TABLE `jos_core_acl_aro_sections` DROP INDEX `jos_gacl_value_aro_sections`;
ALTER TABLE `jos_core_acl_aro_sections` DROP INDEX `jos_gacl_hidden_aro_sections`;



****************************************************

Query 10:

jos_core_log_searches has no indexes at all.

Solution:
Would make sense to add an index on hits (so the table is pre-sorted when displaying top searches), as well as an index on search_term (so adding hits is quick):

ALTER TABLE  `jos_core_log_searches` ADD INDEX (  `hits` );
ALTER TABLE  `jos_core_log_searches` ADD INDEX (  `search_term` ( 16 ) )

********************************************************

Query 11:

jos_core_log_items and jos_stats_agents have no index at all.

It would probably make sense to create indexes: not sure which are needed.


**********************************************************

Suggestion 12:

NULL fields: avoid them as much as possible, they make "holes" in indexes, lowering performance more often than increasing it.

e.g. jos_content.date (date 000-00-00 00:00:00 can be used similar way...and has to be handled as well as such).

SOLUTION: change DEFAULT NULL and add NOT NULL in table creations.


(this one might need a little more tests before going to stable, but hey, it's the right time).

***********************************************************

That's it for today....

_________________
Beat 8)
www.joomlapolis.com <= Community Builder + CBSubs Joomla membership payment system - team
hosting.joomlapolis.com <= Joomla! Hosting, by the CB Team


Top
  E-mail  
 
Posted: Fri Apr 13, 2007 2:50 am 
User avatar
Joomla! Champion
Joomla! Champion
Offline

Joined: Fri Aug 12, 2005 12:47 am
Posts: 6429
Thanks Beat ! Long time no see on the forums hehe. I'll ask our database experts to have a look and make sure it ends up in SVN.

In the mean time I have added this to our task tracker on the forge :
(Link : http://joomlacode.org/gf/project/joomla ... tem_id=364)

_________________
Johan Janssens - Joomla Co-Founder, Lead Developer of Joomla 1.5

http://www.nooku.org - multi-lingual content manager and rapid extension development framework for Joomla 1.5
http://www.joomlatools.eu - training, consulting and extension development


Last edited by Jinx on Fri Apr 13, 2007 2:55 am, edited 1 time in total.

Top
   
 
Posted: Fri Apr 13, 2007 8:22 am 
User avatar
Joomla! Master
Joomla! Master
Offline

Joined: Fri Aug 12, 2005 3:47 pm
Posts: 11124
Location: •Translation Matters•
Jinx wrote:
Thanks Beat ! Long time no see on the forums hehe. I'll ask our database experts to have a look and make sure it ends up in SVN.

In the mean time I have added this to our task tracker on the forge :
(Link : http://joomlacode.org/gf/project/joomla ... tem_id=364)


Permission denied for the link.

_________________
Jean-Marie Simonet / infograf · http://www.info-graf.fr · GMT +1
Qui vult dare parva non debet magna rogare.
---------------------------------
Joomla! Translation Coordination Team


Top
  E-mail  
 
Posted: Fri Apr 13, 2007 11:55 am 
User avatar
Joomla! Virtuoso
Joomla! Virtuoso
Offline

Joined: Tue Sep 13, 2005 12:22 am
Posts: 4026
Location: Omaha, Nebraska, USA
You are correct JM.

It appears that only the Tracker type "issues" is viewable to the public. The Tasks, specifically, "Joomla! Development Workgroup Tasks" are not viewable to the public. I can assure you that it is in there and assign to a developer. :)

_________________
Kenneth Crowder - Omaha, Nebraska, USA
Joomla! ...because open source matters


Top
  E-mail  
 
Posted: Fri Apr 13, 2007 2:47 pm 
User avatar
Joomla! Champion
Joomla! Champion
Offline

Joined: Fri Aug 12, 2005 12:47 am
Posts: 6429
Thanks JM, I'll check if we can make the task tracker public without giving access to non-project members.

_________________
Johan Janssens - Joomla Co-Founder, Lead Developer of Joomla 1.5

http://www.nooku.org - multi-lingual content manager and rapid extension development framework for Joomla 1.5
http://www.joomlatools.eu - training, consulting and extension development


Top
   
 
Posted: Mon Apr 16, 2007 8:35 pm 
User avatar
Joomla! Guru
Joomla! Guru
Offline

Joined: Sat Sep 10, 2005 10:31 pm
Posts: 823
Thanks a lot Beat! I've not yet managed to look into this in detail, but we'll get to it...

Beat wrote:
Query 11:

jos_core_log_items and jos_stats_agents have no index at all.

It would probably make sense to create indexes: not sure which are needed.


Just wanted to add a pointer to http://forum.joomla.org/index.php/topic,160762.0.html

_________________
We may not be able to control the wind, but we can always adjust our sails


Top
   
 
Posted: Mon Apr 16, 2007 8:46 pm 
User avatar
Joomla! Guru
Joomla! Guru
Offline

Joined: Thu Aug 18, 2005 8:53 am
Posts: 700
Location: Switzerland
friesengeist wrote:
Thanks a lot Beat! I've not yet managed to look into this in detail, but we'll get to it...

Beat wrote:
Query 11:

jos_core_log_items and jos_stats_agents have no index at all.

It would probably make sense to create indexes: not sure which are needed.


Just wanted to add a pointer to http://forum.joomla.org/index.php/topic,160762.0.html


Thanks, good addition. I replied to that post with a suggestion for a covering index, with other order of keys, more general, so usable by other queries.

_________________
Beat 8)
www.joomlapolis.com <= Community Builder + CBSubs Joomla membership payment system - team
hosting.joomlapolis.com <= Joomla! Hosting, by the CB Team


Top
  E-mail  
 
Posted: Mon Apr 16, 2007 9:03 pm 
Joomla! Apprentice
Joomla! Apprentice
Offline

Joined: Tue Aug 30, 2005 8:05 am
Posts: 48
I would really like to have these modifications performed on my news portal. Today we had an event that went nationwide (shooting at a local university) and thousands of people tried to access our site, causing a huge bogdown on the server.  Is there a Joomla guru available who would quote us a price for doing this type of modification or providing some sort of script that would do them?  I have a dedicated server with probably thirty Joomla sites, none of them come close to the traffic of our news portal site, but this sounds like what we really need done.


Top
  E-mail  
 
Posted: Fri Apr 20, 2007 10:36 am 
User avatar
Joomla! Enthusiast
Joomla! Enthusiast
Offline

Joined: Sun Aug 21, 2005 11:41 pm
Posts: 128
Location: UK
Hi Beat,
This post with  optimisations are well appreciated by all I'm sure.
Is there any way a sql script can be released to make these mods to 1.0.12, either for all or one change at a time?

Best wishes,

- Vince

_________________
www.hostbaron.com - low price Joomla starter packages.

www.MySQLbackup.info - Automated MySQL Backup script.


Top
  E-mail  
 
Posted: Mon May 14, 2007 11:18 pm 
User avatar
Joomla! Enthusiast
Joomla! Enthusiast
Offline

Joined: Fri Aug 12, 2005 7:50 pm
Posts: 177
Location: New York City
Just did some testing with your recommendations Beat, and I can give them a thumbs up, for what it's worth.

Your last recommendation is not such a good idea, as there's a lot of code laying around that is expecting that data to be stored that way - changing it could have unexpected results. That whole date being either NULL or "0000-00-00 00:00:00" makes supporting real databases like PostgreSQL very difficult, as they simply don't tolerate such nonsense ;)

The one caveat to what you are recommending is that most sites won't have enough rows in jos_users to make use of an index anyway LOL

However, in that case, the query optimizer simply refuses the indexes anyway and does scans. Try it on a stock install with sample data, you will see that most indexes are ignored as all the tables have less than 100 rows. So what that means is your index additions don't cause any additional pain and suffering to sites that don't make use of them, as the query optimizer is smart enough to blow them off under those circumstances.

Thanks Beat for sharing your results with us! Cool.  8)

_________________
Bringing on that Spacemonkey goodness:
website -> www.spacemonkeylabs.com
blog -> blog.spacemonkeylabs.com


Top
  E-mail  
 
Posted: Tue May 15, 2007 12:34 am 
User avatar
Joomla! Intern
Joomla! Intern
Offline

Joined: Fri Sep 02, 2005 7:50 am
Posts: 77
Location: Sydney, Australia
Have these optimisations made it into 1.5? 

I would hate to see Beat's contribution stay on the shelf too long when he has dished them up on a silver plater (and I would love to get the benefit of the speed improvements ;) )

Hope you core guys had a great time at the Googleplex - sounds like it was a good mix of work and fun!


Top
  E-mail  
 
Posted: Thu Aug 09, 2007 4:46 pm 
User avatar
Joomla! Guru
Joomla! Guru
Offline

Joined: Thu Aug 18, 2005 8:53 am
Posts: 700
Location: Switzerland
No idea if this costly contribution has been integrated in Joomla 1.5....but anyway, as public note to myself :D :

For query 11 optimization, here what's needed:

ALTER TABLE `jos_stats_agents` ADD INDEX `type_agent` ( `type` , `agent` );


for optimizing query:

UPDATE jos_stats_agents
SET hits = ( hits + 1 )
WHERE agent = 'MS Internet Explorer 7.0'
AND type = 0

+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table            | type | possible_keys | key  | key_len | ref  | rows | Extra      |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | jos_stats_agents | ALL  | NULL          | NULL |    NULL | NULL |  785 | Using where |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+

ALTER TABLE `jos_stats_agents` ADD INDEX `type_agent` ( `type` , `agent` );

+----+-------------+------------------+------+---------------+------------+---------+-------------+------+-------------+
| id | select_type | table            | type | possible_keys | key        | key_len | ref        | rows | Extra      |
+----+-------------+------------------+------+---------------+------------+---------+-------------+------+-------------+
|  1 | SIMPLE      | jos_stats_agents | ref  | type_agent    | type_agent |    766 | const,const |    1 | Using where |
+----+-------------+------------------+------+---------------+------------+---------+-------------+------+-------------+


Also as note for myself and for others, these queries above are here put together, and work fine on Joomla 1.0.x too:

Code:
ALTER TABLE `jos_core_acl_aro` ADD UNIQUE INDEX `value` ( `value` ) ;
ALTER TABLE `jos_core_acl_groups_aro_map` ADD INDEX `aro_id` ( `aro_id` ) ;
CREATE INDEX idxemail ON jos_users ( `email` );
ALTER TABLE `jos_content` ADD INDEX `idx_created_by` ( `created_by` ) ;
ALTER TABLE `jos_users` DROP INDEX `block_regdate`;
ALTER TABLE `jos_users` ADD INDEX `block_id` ( `block` , `id` );
ALTER TABLE `jos_users` ADD INDEX `username` ( `username` );
ALTER TABLE `jos_session` ADD INDEX `userid` ( `userid` );
ALTER TABLE `jos_categories` DROP INDEX `idx_section`;
ALTER TABLE `jos_core_acl_aro_sections` DROP INDEX `jos_gacl_value_aro_sections`;
ALTER TABLE `jos_core_acl_aro_sections` DROP INDEX `jos_gacl_hidden_aro_sections`;
ALTER TABLE `jos_core_log_searches` ADD INDEX ( `hits` ) ;
ALTER TABLE `jos_core_log_searches` ADD INDEX ( `search_term` ( 16 ) ) ;
ALTER TABLE `jos_stats_agents` ADD INDEX `type_agent` ( `type` , `agent` );


Enjoy Joomla 1.0 (and 1.5) speed :)

_________________
Beat 8)
www.joomlapolis.com <= Community Builder + CBSubs Joomla membership payment system - team
hosting.joomlapolis.com <= Joomla! Hosting, by the CB Team


Top
  E-mail  
 
Posted: Mon Aug 13, 2007 10:43 am 
Joomla! Fledgling
Joomla! Fledgling
Offline

Joined: Wed May 17, 2006 6:44 am
Posts: 4
Joomla 1.0.13 users beware - I just tried it and after the DB updates, the site got errors!

Beat, can you please update the queries for Joomla 1.0.x?


Top
  E-mail  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

Quick reply

 



Who is online

Users browsing this forum: atilerturk and 16 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group