views:

501

answers:

2

Hi,

this is a follow up from http://stackoverflow.com/questions/1242223/mysql-find-rows-matching-all-rows-from-joined-table

Thanks to this site the query runs perfectly.

But now i had to extend the query for a search for artist and track. This has lead me to the following query:

SELECT DISTINCT`t`.`id` 
FROM `trackwords` AS `tw`  
INNER JOIN `wordlist` AS `wl` ON wl.id=tw.wordid  
INNER JOIN `track` AS `t` ON tw.trackid=t.id  
WHERE (wl.trackusecount>0) AND  
(wl.word IN ('please','dont','leave','me')) AND  
t.artist IN ( 
 SELECT a.id  
 FROM artist as a 
 INNER JOIN `artistalias` AS `aa` ON aa.ref=a.id  
 WHERE a.name LIKE 'pink%' OR  aa.name LIKE 'pink%' 
)  
GROUP BY tw.trackid 
HAVING (COUNT(*) = 4);

The Explain for this query looks quite good i think:

+----+--------------------+-------+--------+----------------------------+---------+---------+-----------------+------+----------------------------------------------+
| id | select_type        | table | type   | possible_keys              | key     | key_len | ref             | rows | Extra                                        |
+----+--------------------+-------+--------+----------------------------+---------+---------+-----------------+------+----------------------------------------------+
|  1 | PRIMARY            | wl    | range  | PRIMARY,word,trackusecount | word    | 767     | NULL            |    4 | Using where; Using temporary; Using filesort | 
|  1 | PRIMARY            | tw    | ref    | wordid,trackid             | wordid  | 4       | mbdb.wl.id      |   31 |                                              | 
|  1 | PRIMARY            | t     | eq_ref | PRIMARY                    | PRIMARY | 4       | mbdb.tw.trackid |    1 | Using where                                  | 
|  2 | DEPENDENT SUBQUERY | aa    | ref    | ref,name                   | ref     | 4       | func            |    2 |                                              | 
|  2 | DEPENDENT SUBQUERY | a     | eq_ref | PRIMARY,name,namefull      | PRIMARY | 4       | func            |    1 | Using where                                  | 
+----+--------------------+-------+--------+----------------------------+---------+---------+-----------------+------+----------------------------------------------+

Did you see room for optimization ? Query has a runtime from around 7secs, which is to much unfortunatly. Any suggestions are welcome.

TIA

A: 

Have you already indexed the name columns? That should speed this up.

You can also try using fulltext searching with Match and Against.

IPX Ares
+1  A: 

You have two possible selective conditions here: artists's name and the word list.

Assuming that the words are more selective than artists:

SELECT  tw.trackid 
FROM    (
        SELECT  tw.trackid
        FROM    wordlist AS wl
        JOIN    trackwords AS tw  
        ON      tw.wordid = wl.id
        WHERE   wl.trackusecount > 0
                AND wl.word IN ('please','dont','leave','me')
        GROUP BY
                tw.trackid
        HAVING  COUNT(*) = 4
        ) tw
INNER JOIN
        track AS t
ON      t.id = tw.trackid
        AND EXISTS
        (
        SELECT  NULL
        FROM    artist a
        WHERE   a.name LIKE 'pink%'
                AND a.id = t.artist
        UNION ALL
        SELECT  NULL
        FROM    artist a
        JOIN    artistalias aa
        ON      aa.ref = a.id
                AND aa.name LIKE 'pink%'
        WHERE   a.id = t.artist
        )

You need to have the following indexes for this to be efficient:

wordlist (word, trackusecount)
trackwords (wordid, trackid)
artistalias (ref, name)
Quassnoi
wow, nice. i think i undertand what you are doing, but mysql is giving:#1248 - Every derived table must have its own aliasas far as i understand it, it should be the track (t) which gave the error, but i can't figure out how to fix this.
Rufinus
@Rufinus: oh, sorry. Fixed.
Quassnoi
`@Rufinus`: it would be very nice if you would post the table definitions along with the query so that people could check the syntax before posting.
Quassnoi
@Quassnoi: Thanks THanks Thanks. its about 700% faster then my version, its awsome ! Next time i will link a sql structure file. (dont wanted to blow the question up with 5 table structures :-)Thanks again
Rufinus
`@Rufinus`: you're welcome :) It's perfectly ok to "blow the question": it's super easy to get rid of the structure but very hard to make it up if you don't know it.
Quassnoi