简体   繁体   中英

Very slow MySql queries Joomla 2.5

My website is experiencing very slow queries like the one below. It is Joomla 2.5.

# Query_time: 19.797091  Lock_time: 0.000561 Rows_sent: 12  Rows_examined: 4127
SET timestamp=1385467501;
SELECT a.fulltext, a.id, a.title, a.alias, a.title_alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias,a.images, a.modified, a.modified_by,a.publish_up, a.publish_down, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.featured, LENGTH(a.fulltext) AS readmore,a.fulltext, a.id, a.title, a.alias, a.title_alias, a.introtext, a.state, a.catid, a.created, a.created_by, a.created_by_alias,a.images, a.modified, a.modified_by,a.publish_up, a.publish_down, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.featured, LENGTH(a.fulltext) AS readmore,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 j25_content AS a
LEFT JOIN j25_content_frontpage AS fp ON fp.content_id = a.id
LEFT JOIN j25_categories AS c ON c.id = a.catid
LEFT JOIN j25_users AS ua ON ua.id = a.created_by
LEFT JOIN j25_users AS uam ON uam.id = a.modified_by
LEFT JOIN (
SELECT contact.user_id, MAX(contact.id) AS id, contact.language
FROM j25_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 j25_categories as parent ON parent.id = c.parent_id
LEFT JOIN j25_content_rating AS v ON a.id = v.content_id
LEFT OUTER JOIN (SELECT cat.id as id FROM j25_categories AS cat JOIN j25_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) AND c.access IN (1,1) AND CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1 AND a.featured = 0 AND a.catid IN (181,89,173,174,49,128,124,175,129,133,121,176,135,180,177,178,179,90) AND (a.publish_up = '0000-00-00 00:00:00' OR a.publish_up <= '2013-11-26 12:04:24') AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2013-11-26 12:04:24')
GROUP BY a.id, a.title, a.alias, a.title_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 a.created DESC LIMIT 0, 12;

What can I do to speed it up? Would indexing some of these tables help? Thank you.

Absolutely indexes help in queries. And each of what I consider your secondary lookup reference tables (categories, users, content rating, etc) should have an index at a MINIMUM on what your join condition is between the tables.

table                 index on
j25_content           ( access, featured, catid, publish_up, publish_down, state, id, created_by, modified_by )
j25_content_frontpage ( content_id )
j25_categories        ( id, parent_id )
ANOTHER index...
j25_categories        ( extension, published, lft, rgt, id )
j25_users             ( id )
j25_contact_details   ( published, user_id, language, id )
j25_content_rating    ( content_id )

I've set these indexes up to be "covering" indexes... meaning they should help the optimization of the query by having all the fields as part of the index so it does not have to go to the raw data pages to see if all the pieces qualify to return a record

TRY that first...

NEXT thing I would try is MySQL has a special keyword "STRAIGHT_JOIN" which tells the engine to run the query in the order you have stated. You seem to have a good basis of the tables as the primary and your lookup as secondary. The engine might be trying to think for you and use one of the smaller tables to run the query.

select STRAIGHT_JOIN  (rest of your query exactly as it is)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM