简体   繁体   English

如何优化此慢查询?

[英]How I can optimize this slow query?

I want to know how I can optimize it, preferably without changes in tables structure. 我想知道如何优化它,最好不更改表结构。

SELECT p.author_id member_id,
       m.members_display_name member_name,
       COUNT(p.pid) posts
FROM forum_topics t
     STRAIGHT_JOIN forum_posts p
     STRAIGHT_JOIN forum_members m
WHERE p.author_id != 0
      AND p.author_id = m.member_id
      AND p.new_topic = 0
      AND t.forum_id = 120
      AND t.tid = p.topic_id
GROUP BY p.author_id
ORDER BY posts DESC
LIMIT 1

Output of EXPLAIN is: EXPLAIN输出为:

-------------------------------------------------------------------------------
 EXPLAIN
  SELECT p.author_id member_id,
         m.members_display_name member_name,
         COUNT(p.pid) posts
    FROM forum_topics t
         STRAIGHT_JOIN forum_posts p
         STRAIGHT_JOIN forum_members m
   WHERE p.author_id != 0
         AND p.author_id = m.member_id
         AND p.new_topic = 0
         AND t.forum_id = 120
         AND t.tid = p.topic_id
GROUP BY p.author_id
ORDER BY posts DESC
   LIMIT 1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ref
possible_keys: PRIMARY,forum_id,last_post
          key: forum_id
      key_len: 2
          ref: const
         rows: 28070
        Extra: Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: p
         type: ref
possible_keys: author_id,topic_id
          key: topic_id
      key_len: 4
          ref: forumwmo.t.tid
         rows: 5
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: m
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 3
          ref: forumwmo.p.author_id
         rows: 1
        Extra: 
3 rows in set (0.00 sec)

Table structure is: 表结构为:

SHOW CREATE TABLE forum_members\G
*************************** 1. row ***************************
       Table: forum_members
Create Table: CREATE TABLE `forum_members` (
  `member_id` mediumint(8) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '',
  `member_group_id` smallint(3) NOT NULL DEFAULT '0',
  `email` varchar(150) NOT NULL DEFAULT '',
  `joined` int(10) NOT NULL DEFAULT '0',
  `ip_address` varchar(16) NOT NULL DEFAULT '',
  `posts` mediumint(7) DEFAULT '0',
  `title` varchar(64) DEFAULT NULL,
  `allow_admin_mails` tinyint(1) DEFAULT NULL,
  `time_offset` varchar(10) DEFAULT NULL,
  `hide_email` varchar(8) DEFAULT NULL,
  `email_pm` tinyint(1) DEFAULT NULL,
  `email_full` tinyint(1) DEFAULT NULL,
  `skin` smallint(5) DEFAULT NULL,
  `warn_level` int(10) DEFAULT NULL,
  `warn_lastwarn` int(10) NOT NULL DEFAULT '0',
  `language` varchar(32) DEFAULT NULL,
  `last_post` int(10) DEFAULT NULL,
  `restrict_post` varchar(100) NOT NULL DEFAULT '0',
  `view_sigs` tinyint(1) DEFAULT '1',
  `view_img` tinyint(1) DEFAULT '1',
  `view_avs` tinyint(1) DEFAULT '1',
  `view_pop` tinyint(1) DEFAULT '1',
  `bday_day` int(2) DEFAULT NULL,
  `bday_month` int(2) DEFAULT NULL,
  `bday_year` int(4) DEFAULT NULL,
  `msg_count_new` int(2) NOT NULL DEFAULT '0',
  `msg_count_total` int(3) NOT NULL DEFAULT '0',
  `msg_count_reset` int(1) NOT NULL DEFAULT '0',
  `msg_show_notification` int(1) NOT NULL DEFAULT '0',
  `misc` varchar(128) DEFAULT NULL,
  `last_visit` int(10) DEFAULT '0',
  `last_activity` int(10) DEFAULT '0',
  `dst_in_use` tinyint(1) DEFAULT '0',
  `view_prefs` varchar(64) DEFAULT '-1&-1',
  `coppa_user` tinyint(1) DEFAULT '0',
  `mod_posts` varchar(100) NOT NULL DEFAULT '0',
  `auto_track` varchar(50) DEFAULT '0',
  `org_perm_id` varchar(255) DEFAULT '',
  `temp_ban` varchar(100) DEFAULT '0',
  `sub_end` int(10) NOT NULL DEFAULT '0',
  `no_sig_lims` tinyint(1) NOT NULL DEFAULT '0',
  `login_anonymous` char(3) NOT NULL DEFAULT '0&0',
  `ignored_users` text,
  `mgroup_others` varchar(255) NOT NULL DEFAULT '',
  `member_login_key` varchar(32) NOT NULL DEFAULT '',
  `member_login_key_expire` int(10) NOT NULL DEFAULT '0',
  `subs_pkg_chosen` smallint(3) NOT NULL DEFAULT '0',
  `has_blog` tinyint(1) NOT NULL DEFAULT '0',
  `members_auto_dst` tinyint(1) NOT NULL DEFAULT '1',
  `members_cache` mediumtext,
  `members_disable_pm` int(1) NOT NULL DEFAULT '0',
  `members_display_name` varchar(255) NOT NULL DEFAULT '',
  `members_seo_name` varchar(255) NOT NULL DEFAULT '',
  `members_created_remote` tinyint(1) NOT NULL DEFAULT '0',
  `members_editor_choice` char(3) NOT NULL DEFAULT 'std',
  `members_profile_views` int(10) unsigned NOT NULL DEFAULT '0',
  `members_l_display_name` varchar(255) NOT NULL DEFAULT '0',
  `members_l_username` varchar(255) NOT NULL DEFAULT '0',
  `failed_logins` text,
  `failed_login_count` smallint(3) NOT NULL DEFAULT '0',
  `has_gallery` int(1) DEFAULT '0',
  `members_pass_hash` varchar(32) NOT NULL DEFAULT '',
  `members_pass_salt` varchar(5) NOT NULL DEFAULT '',
  `member_banned` tinyint(1) NOT NULL DEFAULT '0',
  `identity_url` text,
  `member_uploader` varchar(32) NOT NULL DEFAULT 'default',
  `members_bitoptions` int(10) unsigned NOT NULL DEFAULT '0',
  `fb_uid` bigint(20) NOT NULL DEFAULT '0',
  `fb_emailhash` varchar(60) NOT NULL DEFAULT '',
  `fb_emailallow` int(1) NOT NULL DEFAULT '0',
  `fb_lastsync` int(10) NOT NULL DEFAULT '0',
  `members_day_posts` varchar(32) NOT NULL DEFAULT '0,0',
  `live_id` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`member_id`),
  KEY `mgroup` (`member_group_id`),
  KEY `bday_day` (`bday_day`),
  KEY `bday_month` (`bday_month`),
  KEY `members_l_display_name` (`members_l_display_name`),
  KEY `members_l_username` (`members_l_username`),
  KEY `member_banned` (`member_banned`),
  KEY `members_bitoptions` (`members_bitoptions`),
  KEY `ip_address` (`ip_address`)
) ENGINE=MyISAM AUTO_INCREMENT=101965 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
-------------------------------------------------------------------------------
SHOW CREATE TABLE forum_posts\G
*************************** 1. row ***************************
       Table: forum_posts
Create Table: CREATE TABLE `forum_posts` (
  `append_edit` tinyint(1) DEFAULT '0',
  `edit_time` int(10) DEFAULT NULL,
  `pid` int(10) NOT NULL AUTO_INCREMENT,
  `author_id` mediumint(8) NOT NULL DEFAULT '0',
  `author_name` varchar(32) DEFAULT NULL,
  `use_sig` tinyint(1) NOT NULL DEFAULT '0',
  `use_emo` tinyint(1) NOT NULL DEFAULT '0',
  `ip_address` varchar(16) NOT NULL DEFAULT '',
  `post_date` int(10) DEFAULT NULL,
  `icon_id` smallint(3) DEFAULT NULL,
  `post` mediumtext,
  `queued` tinyint(1) NOT NULL DEFAULT '0',
  `topic_id` int(10) NOT NULL DEFAULT '0',
  `post_title` varchar(255) DEFAULT NULL,
  `new_topic` tinyint(1) DEFAULT '0',
  `edit_name` varchar(255) DEFAULT NULL,
  `post_parent` int(10) NOT NULL DEFAULT '0',
  `post_key` varchar(32) NOT NULL DEFAULT '0',
  `post_htmlstate` smallint(1) NOT NULL DEFAULT '0',
  `post_edit_reason` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`pid`),
  KEY `author_id` (`author_id`,`topic_id`),
  KEY `post_date` (`post_date`),
  KEY `topic_id` (`topic_id`,`queued`,`pid`,`post_date`),
  KEY `post_key` (`post_key`),
  KEY `ip_address` (`ip_address`)
) ENGINE=MyISAM AUTO_INCREMENT=988489 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
-------------------------------------------------------------------------------
SHOW CREATE TABLE forum_topics\G
*************************** 1. row ***************************
       Table: forum_topics
Create Table: CREATE TABLE `forum_topics` (
  `tid` int(10) NOT NULL AUTO_INCREMENT,
  `title` varchar(70) NOT NULL DEFAULT '',
  `description` varchar(250) DEFAULT NULL,
  `state` varchar(8) DEFAULT NULL,
  `posts` int(10) DEFAULT NULL,
  `starter_id` mediumint(8) NOT NULL DEFAULT '0',
  `start_date` int(10) DEFAULT NULL,
  `last_poster_id` mediumint(8) NOT NULL DEFAULT '0',
  `last_post` int(10) DEFAULT NULL,
  `icon_id` tinyint(2) DEFAULT NULL,
  `starter_name` varchar(255) DEFAULT NULL,
  `last_poster_name` varchar(255) DEFAULT NULL,
  `poll_state` varchar(8) DEFAULT NULL,
  `last_vote` int(10) DEFAULT NULL,
  `views` int(10) DEFAULT '0',
  `forum_id` smallint(5) NOT NULL DEFAULT '0',
  `approved` tinyint(1) NOT NULL DEFAULT '0',
  `author_mode` tinyint(1) DEFAULT NULL,
  `pinned` tinyint(1) NOT NULL DEFAULT '0',
  `moved_to` varchar(64) DEFAULT NULL,
  `total_votes` int(5) NOT NULL DEFAULT '0',
  `topic_hasattach` smallint(5) NOT NULL DEFAULT '0',
  `topic_firstpost` int(10) NOT NULL DEFAULT '0',
  `topic_queuedposts` int(10) NOT NULL DEFAULT '0',
  `topic_rating_total` smallint(5) unsigned NOT NULL DEFAULT '0',
  `topic_rating_hits` smallint(5) unsigned NOT NULL DEFAULT '0',
  `topic_open_time` int(10) NOT NULL DEFAULT '0',
  `topic_close_time` int(10) NOT NULL DEFAULT '0',
  `title_seo` varchar(250) NOT NULL DEFAULT '',
  `seo_last_name` varchar(255) NOT NULL DEFAULT '',
  `seo_first_name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`tid`),
  KEY `topic_firstpost` (`topic_firstpost`),
  KEY `forum_id` (`forum_id`,`pinned`,`approved`),
  KEY `last_post` (`forum_id`,`pinned`,`last_post`),
  KEY `starter_id` (`starter_id`,`forum_id`,`approved`),
  KEY `last_post_sorting` (`last_post`,`forum_id`),
  KEY `start_date` (`start_date`),
  FULLTEXT KEY `title` (`title`)
) ENGINE=MyISAM AUTO_INCREMENT=227233 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

Table properties are: 表属性是:

SHOW TABLE STATUS LIKE 'forum_members'\G
*************************** 1. row ***************************
           Name: forum_members
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 64866
 Avg_row_length: 257
    Data_length: 16688164
Max_data_length: 281474976710655
   Index_length: 6540288
      Data_free: 0
 Auto_increment: 101965
    Create_time: 2009-12-02 05:45:59
    Update_time: 2009-12-02 05:46:07
     Check_time: 2009-12-02 05:49:23
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)
-------------------------------------------------------------------------------
SHOW TABLE STATUS LIKE 'forum_posts'\G
*************************** 1. row ***************************
           Name: forum_posts
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 581777
 Avg_row_length: 720
    Data_length: 419170168
Max_data_length: 281474976710655
   Index_length: 46439424
      Data_free: 0
 Auto_increment: 988489
    Create_time: 2009-12-02 05:47:04
    Update_time: 2009-12-02 05:48:13
     Check_time: 2009-12-02 05:49:28
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)
-------------------------------------------------------------------------------
SHOW TABLE STATUS LIKE 'forum_topics'\G
*************************** 1. row ***************************
           Name: forum_topics
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 117458
 Avg_row_length: 144
    Data_length: 17004836
Max_data_length: 281474976710655
   Index_length: 14105600
      Data_free: 0
 Auto_increment: 227233
    Create_time: 2009-12-02 05:48:38
    Update_time: 2009-12-02 05:48:43
     Check_time: 2009-12-02 05:49:28
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)

Other configuration details: 其他配置详细信息:

SHOW VARIABLES LIKE '%buffer%'\G
*************************** 1. row ***************************
Variable_name: bulk_insert_buffer_size
        Value: 8388608
*************************** 2. row ***************************
Variable_name: innodb_buffer_pool_size
        Value: 8388608
*************************** 3. row ***************************
Variable_name: innodb_log_buffer_size
        Value: 1048576
*************************** 4. row ***************************
Variable_name: join_buffer_size
        Value: 131072
*************************** 5. row ***************************
Variable_name: key_buffer_size
        Value: 8384512
*************************** 6. row ***************************
Variable_name: myisam_sort_buffer_size
        Value: 8388608
*************************** 7. row ***************************
Variable_name: net_buffer_length
        Value: 16384
*************************** 8. row ***************************
Variable_name: pbxt_log_buffer_size
        Value: 256K
*************************** 9. row ***************************
Variable_name: pbxt_transaction_buffer_size
        Value: 1MB
*************************** 10. row ***************************
Variable_name: preload_buffer_size
        Value: 32768
*************************** 11. row ***************************
Variable_name: read_buffer_size
        Value: 131072
*************************** 12. row ***************************
Variable_name: read_rnd_buffer_size
        Value: 262144
*************************** 13. row ***************************
Variable_name: sort_buffer_size
        Value: 2097144
*************************** 14. row ***************************
Variable_name: sql_buffer_result
        Value: OFF
14 rows in set (0.00 sec)

You might gain increased performance by moving some of your WHERE clause conditions up into your JOINs since this will cut down the result set as the query is executed eg 通过将一些WHERE子句条件上移到JOIN中,可能会提高性能,因为这会在执行查询时减少结果集,例如

SELECT p.author_id            member_id,
       m.members_display_name member_name,
       COUNT(p.pid)           posts
FROM forum_topics t
     STRAIGHT_JOIN forum_posts p 
     ON            t.tid      = p.topic_id 
     AND           t.forum_id = 120 
     AND p.new_topic = 0
     STRAIGHT_JOIN forum_members m 
     ON p.author_id = m.member_id
WHERE p.author_id   != 0      
GROUP BY p.author_id
ORDER BY posts DESC
LIMIT 1

Although, the optimizer may be smart enough to do this for you. 尽管,优化器可能足够聪明,可以为您执行此操作。 Also, although I don't use MySQL, my understanding of the STRAIGH_JOIN is that it joins that tables in an explicit left to right order so it may make a difference if the tables are listed in size order from smallest to largest and vica versa. 另外,尽管我不使用MySQL,但我对STRAIGH_JOIN的理解是它以明确的从左到右的顺序连接该表,因此,如果按大小顺序(从最小到最大,反之亦然)列出表,可能会有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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