2011-08-10 11 views
1

これはこのMySQLクエリを改善するには?

# [email protected]: appUser[appUser] @ [192.168.1.10] 
# Query_time: 65.118800 Lock_time: 0.000257 Rows_sent: 7 Rows_examined: 78056 
SET timestamp=1312883519; 
select 
    this_.id as id2_0_, 
    this_.appearance_count as appearance2_2_0_, 
    this_.author as author2_0_, 
    this_.date_added as date4_2_0_, 
    this_.date_last_ranked as date5_2_0_, 
    this_.date_updated as date6_2_0_, 
    this_.description as descript7_2_0_, 
    this_.frequency_updated as frequency8_2_0_, 
    this_.hidden as hidden2_0_, 
    this_.link as link2_0_, 
    this_.lock_id as lock11_2_0_, 
    this_.plain_text_description as plain12_2_0_, 
    this_.processor_done as processor13_2_0_, 
    this_.processor_lock_id as processor14_2_0_, 
    this_.published_date as published15_2_0_, 
    this_.raw_link as raw16_2_0_, 
    this_.retweet_count as retweet17_2_0_, 
    this_.source_url as source18_2_0_, 
    this_.subtype as subtype2_0_, 
    this_.thumbnail_img_url as thumbnail20_2_0_, 
    this_.title as title2_0_, 
    this_.total_hit_count as total22_2_0_, 
    this_.total_lift_count as total23_2_0_, 
    this_.total_share_count as total24_2_0_, 
    this_.trend_value as trend25_2_0_, 
    this_.type as type2_0_ 
from 
    news this_ 
where 
    exists (select 1 from news_sub_topic where this_.id=news_sub_topics_id) 
order by 
    this_.trend_value desc, 
    this_.retweet_count desc, 
    this_.total_lift_count desc, 
    this_.published_date desc 
limit 7; 

これはEXPLAINを与えるものである私はスローquery.logで見たものである:

+----+--------------------+----------------+------+--------------------------------------+-------------------+---------+------------------------+-------+-----------------------------+ 
| id | select_type  | table   | type | possible_keys      | key    | key_len | ref     | rows | Extra      | 
+----+--------------------+----------------+------+--------------------------------------+-------------------+---------+------------------------+-------+-----------------------------+ 
| 1 | PRIMARY   | this_   | ALL | NULL         | NULL    | NULL | NULL     | 50910 | Using where; Using filesort | 
| 2 | DEPENDENT SUBQUERY | news_sub_topic | ref | FK420C980470B0479,FK420C98041F791FA1 | FK420C980470B0479 | 9  | causelift_web.this_.id |  1 | Using where; Using index | 
+----+--------------------+----------------+------+--------------------------------------+-------------------+---------+------------------------+-------+-----------------------------+ 
2 rows in set (3.28 sec) 

これでニュースやnews_sub_topicテーブルのCREATE sytax:

CREATE TABLE `news` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `appearance_count` int(11) NOT NULL, 
    `author` longtext COLLATE utf8_unicode_ci, 
    `date_added` datetime NOT NULL, 
    `date_updated` datetime DEFAULT NULL, 
    `description` longtext COLLATE utf8_unicode_ci, 
    `link` longtext COLLATE utf8_unicode_ci, 
    `published_date` datetime NOT NULL, 
    `raw_link` longtext COLLATE utf8_unicode_ci, 
    `subtype` varchar(5) COLLATE utf8_unicode_ci NOT NULL, 
    `thumbnail_img_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `title` longtext COLLATE utf8_unicode_ci, 
    `type` varchar(5) COLLATE utf8_unicode_ci NOT NULL, 
    `date_last_ranked` datetime DEFAULT NULL, 
    `lock_id` int(11) DEFAULT NULL, 
    `plain_text_description` longtext COLLATE utf8_unicode_ci, 
    `source_url` longtext COLLATE utf8_unicode_ci, 
    `retweet_count` int(11) DEFAULT NULL, 
    `frequency_updated` bit(1) DEFAULT NULL, 
    `hidden` bit(1) DEFAULT NULL, 
    `processor_done` bit(1) DEFAULT NULL, 
    `processor_lock_id` int(11) DEFAULT NULL, 
    `total_hit_count` int(11) DEFAULT NULL, 
    `total_lift_count` int(11) DEFAULT NULL, 
    `total_share_count` int(11) DEFAULT NULL, 
    `trend_value` float DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `link_idx` (`link`(255)), 
    KEY `type_idx` (`type`), 
    KEY `processor_lock_id_idx` (`processor_lock_id`), 
    KEY `processor_done_idx` (`processor_done`), 
    KEY `hidden_idx` (`hidden`), 
    KEY `title_idx` (`title`(255)), 
    KEY `published_date_idx` (`published_date`) 
) ENGINE=InnoDB AUTO_INCREMENT=321136 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 


CREATE TABLE `news_sub_topic` (
    `news_sub_topics_id` bigint(20) DEFAULT NULL, 
    `sub_topic_id` bigint(20) DEFAULT NULL, 
    KEY `FK420C98045D8019D4` (`sub_topic_id`), 
    KEY `FK420C980470B0479` (`news_sub_topics_id`), 
    CONSTRAINT `FK420C98041F791FA1` FOREIGN KEY (`news_sub_topics_id`) REFERENCES `news` (`id`), 
    CONSTRAINT `FK420C98045D8019D4` FOREIGN KEY (`sub_topic_id`) REFERENCES `sub_topic` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

なぜこのクエリが完了するのに65秒かかるのか誰でも説明できますか?時にはそれは速いですか?私が調べるべき他の要因は何か(DBの設定、OSなど)。

ありがとうございました。

答えて

2

私の気持ちは「WHERE」節です。

は、代わりにこのコードを試してみてください。

from 
    news this_ 
    inner join news_sub_topic topic on this.id=topic.news_sub_topics_id 

ニュースに対して検索がおそらく、filesortレコードではなく、インデックスを使用しているため、WHERE句を最適化するための良いヒントを与えていないので、説明があります。

+0

提案をいただきありがとうございます。私はそれを試みます。クエリはフレームワーク(Grails ORM)によって自動生成されることに注意してください。 – firnnauriel

+0

ああ、私はその部分を認識していませんでした:どのようにあなたのコードでクエリを表現していますか?ニューステーブルのマッピングでjoinTableを使用していますか? –

+0

はい、それは実際にテーブルデザインです:ニュースは1-M NewsSubTopicです。あなたのクエリの提案は実際に元のコードより優れています。 EXPLAINでも優れているように見えます。私はこれが、joinの代わりにuse exists()が使われる理由に関するフレームワークの問題だと思う。時間のためにありがとう。 – firnnauriel

関連する問題