简体   繁体   中英

How to speed this query up?

I'm using yii framework to create a website takes care of poems and words and stuff...

the problem is that the database has more than 250,000 record of messages and more than 500,000 records of keywords and relationships :S

what I'm trying to say that I want to make an optimal query to get all related messages of a specific message depending on key-tags..

what I did so far is caching the query, but it's still slow when opening it for the first time and that's a big problem!

here is my code:

    public function getRelatedMessages()
    {
        $id = $this->id;
        $dependency = "select `messages`.id,count(id) as tag_count from messages left join `messages_tags` on `messages`.`id` = `messages_tags`.mid 
            where `messages_tags`.`tagid` in (select `tags`.`id` from tags left join `messages_tags` on tags.id = `messages_tags`.tagid 
            where `messages_tags`.`mid` = {$id}) and id <> {$id} group by id order by tag_count desc";
        $dependency =  Messages::model()->cache(900)->findAllBySql($dependency);
        foreach ($dependency as $dependency) {
            $dependency1[] = $dependency['id'];
        }
        $dependency = implode(", ", $dependency1);
        $sql = "select * from messages where id in ({$dependency})  limit 4";
        $relateds =  Messages::model()->findAllBySql($sql);
        $db = array();
        foreach($relateds as $related) {
            $db[] = $related;
        }
        if(!$relateds || count($db)<4) {
            $limit = 4-count($db);
            $sql = "select `messages`.id, `messages`.url_key, `messages`.photo_url, `messages`.message from messages order by rand(), likes desc, comments desc, impressions desc, reported asc limit {$limit};";

            $relateds =  Messages::model()->cache(900)->findAllBySql($sql);
            foreach($relateds as $related) {
                $db[] = $related;
            }
        }

        return $db;
    } 

the code above selects only 4 records from the related messages after filtering them and ordering them and stuff.. the problem is with "order by" but I need it :S

sorry if that was too long..

thank you :)

You could improve the first query by not using findAllBySql() and instantiating all the ActiveRecord classes. You don't need them, so use plain sql query like this (query stays the same but code around has changed):

       // ...
       $dependency = $this->dbConnection->createCommand("
           select `messages`.id, count(id) as tag_count
           from messages left join `messages_tags` on `messages`.`id` = `messages_tags`.mid 
           where
               `messages_tags`.`tagid` in 
                  (select `tags`.`id` from tags left join `messages_tags` on tags.id = `messages_tags`.tagid where `messages_tags`.`mid` = {$id})
               and id <> {$id}
           group by id order by tag_count desc")->queryColumn();

       $dependency = implode(", ", $dependency);
       $sql = "select * from messages where id in ({$dependency})  limit 4";
       $relateds =  Messages::model()->findAllBySql($sql);
       // ...

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