Home » Performance » MySQL » Query with inner SELECT is slow
Query with inner SELECT is slow [message #74] Thu, 17 August 2006 11:57 Go to next message
vadim1508  is currently offline vadim1508
Messages: 9
Registered: August 2006
Junior Member
Hi,

I have the following table (userid isn't unique and userid may have more than one subject):

`my_test` (
`userid` int(10) unsigned NOT NULL,
`subject` varchar(100) NOT NULL),
KEY `ind_subject` (`subject`),
KEY `ind_userid` (`userid`),
KEY `ind_userid_subject` (`userid`,`subject`)
ENGINE=MyISAM DEFAULT CHARSET=latin1 |

I need to perform the following query, which is very slow:
select subject, count(*) AS Number from (select DISTINCT userid,subject from my_test) AS FILTERED GROUP BY subject ORDER BY Number DESC;

However, the following two queries are very,very fast:
select DISTINCT userid,subject from my_test;
and
select subject, count(*) AS Number from my_test AS FILTERED GROUP BY subject ORDER BY Number DESC;

What is the problem with my inner select query? How I make it faster?

Thanks a lot!

Vadim
Re: Query with inner SELECT is slow [message #76 is a reply to message #74 ] Thu, 17 August 2006 12:17 Go to previous messageGo to next message
Peter  is currently offline Peter
Messages: 405
Registered: August 2006
Senior Member
Super Guru
First about table structure - you might want to read my blog article from today:

http://www.mysqlperformanceblog.com/2006/08/17/duplicate-ind exes-and-redundant-indexes/


Speaking about queries - providing EXPLAIN would be helpful.

I guess both of fast queries are indexed, while if you use SELECT in FROM clause you get result set back which does not have any indexes. Also MySQL will normally materialize such subselects in temporary table which also may add significant overhead.

Generally I would avoid subselects in FROM clause unless really needed.


Peter Zaitsev, MySQL Performance Expert
MySQL Performance Blog - http://www.mysqlperformanceblog.com
MySQL Consulting http://www.mysqlperformanceblog.com/mysql-consulting/
Re: Query with inner SELECT is slow [message #77 is a reply to message #76 ] Thu, 17 August 2006 13:27 Go to previous messageGo to next message
vadim1508  is currently offline vadim1508
Messages: 9
Registered: August 2006
Junior Member
Thanks for pointing to you post. According to it seems I can remove my KEY `ind_subject` (`subject`) and
KEY `ind_userid` (`userid`).

Concerning subselecting: how you would avoid it in my case?

Suppose my data is as follows:

userid subject
1 How to become rich?
1 How to find a love?
1 How to find a love?
3 How to become rich?
3 How to sleep at night?

Desired result:
How to become rich? 2
How to find a love? 1
How to sleep at night? 1


I really appreciate your help!
Vadim
Re: Query with inner SELECT is slow [message #78 is a reply to message #77 ] Thu, 17 August 2006 13:32 Go to previous messageGo to next message
Peter  is currently offline Peter
Messages: 405
Registered: August 2006
Senior Member
Super Guru
No. You can only remove userid as subject is needed for queries which query only on subject - (user_id,subject) can't help these.

select count(distinct user_id),subject from table group by subject

should do it ?


Peter Zaitsev, MySQL Performance Expert
MySQL Performance Blog - http://www.mysqlperformanceblog.com
MySQL Consulting http://www.mysqlperformanceblog.com/mysql-consulting/
Re: Query with inner SELECT is slow [message #79 is a reply to message #78 ] Fri, 18 August 2006 06:24 Go to previous messageGo to next message
vadim1508  is currently offline vadim1508
Messages: 9
Registered: August 2006
Junior Member
1. Is there reason that I can't remove the "subject" index, but can remove the "userid" index because in my composite index I have (userid,subject) and the userid, which is in first position serves also as single userid index?

2. Your select count(distinct user_id),subject from table group by subject does exactly what I need, but unless I added an additional index: (subject,userid) it was also very slow. As you are saying in your post: "Order of columns in index is significant, index (A,B) is not duplicate to index (B,A)". How I determine the order of composite index?

Thank you!
Re: Query with inner SELECT is slow [message #80 is a reply to message #79 ] Fri, 18 August 2006 06:37 Go to previous message
Peter  is currently offline Peter
Messages: 405
Registered: August 2006
Senior Member
Super Guru
1.

Yes userid can be removed because it is prefix of (userid,subject)

2. I did not say it would be fast Smile I just shown how query should look. Yes this querty benefits of (subject,userid) key because it can perform index scan in this case while if there is index only on subject row reads would be required

About choosing (A,B) or (B,A) you just look at your queries and see which index they need - it may be one, another or both depending on queries you run.


Peter Zaitsev, MySQL Performance Expert
MySQL Performance Blog - http://www.mysqlperformanceblog.com
MySQL Consulting http://www.mysqlperformanceblog.com/mysql-consulting/
Previous Topic:large table to temp table or direct select ?
Next Topic:1 union Vs. 14 separate queries
Goto Forum:
  


Current Time: Sun Jul 5 22:25:09 EDT 2009

Total time taken to generate the page: 0.01421 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 2.7.7.
Copyright ©2001-2007 FUD Forum Bulletin Board Software

MySQL is a trademark of Sun Microsystems.
InnoDB is a trademark of Oracle Corp.

Percona Performance Forums are a service of Percona, Inc.
Not affiliated with Sun Microsystems or Oracle Corp.