繁体   English   中英

如何在MYSQL中优化此查询?

[英]how to optimize this query in MYSQL?

mysql> explain select a.id,a.title from users c
    ->                                  straight_join iask a on c.id=a.uid
    ->                                         straight_join ianswer b on a.id=b.iaskid
    ->
    ->                                  where (c.last_check is null or b.created>c.last_check) and c.id in (1,2)
    ->                                  group by a.id;
+----+-------------+-------+-------+---------------------------+------------+---------+----------+------+----------------------------------------------+
| id | select_type | table | type  | possible_keys             | key        | key_len | ref      | rows | Extra                                        |
+----+-------------+-------+-------+---------------------------+------------+---------+----------+------+----------------------------------------------+
|  1 | SIMPLE      | c     | range | PRIMARY,i_users_lastcheck | PRIMARY    | 4       | NULL     |    2 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | a     | ref   | PRIMARY,i_iask_uid        | i_iask_uid | 4       | bbs.c.id |    2 |                                              |
|  1 | SIMPLE      | b     | ALL   | i_ianswer_iaskid          | NULL       | NULL    | NULL     |   17 | Using where; Using join buffer               |
+----+-------------+-------+-------+---------------------------+------------+---------+----------+------+----------------------------------------------+
3 rows in set (0.00 sec)

将上面的“(1,2)”更改为“ = 1”,将全部使用索引:

mysql> explain select a.id,a.title from iask a
    ->                                          join ianswer b on a.id=b.iaskid
    ->                                          join users c on c.id=a.uid
    ->                                  where (c.last_check is null or b.created>c.last_check) and c.id=1
    ->                                  group by a.id;
+----+-------------+-------+-------+---------------------------+------------------+---------+----------+------+---------------------------------+
| id | select_type | table | type  | possible_keys             | key              | key_len | ref      | rows | Extra                           |
+----+-------------+-------+-------+---------------------------+------------------+---------+----------+------+---------------------------------+
|  1 | SIMPLE      | c     | const | PRIMARY,i_users_lastcheck | PRIMARY          | 4       | const    |    1 | Using temporary; Using filesort |
|  1 | SIMPLE      | a     | ref   | PRIMARY,i_iask_uid        | i_iask_uid       | 4       | const    |    1 | Using where                     |
|  1 | SIMPLE      | b     | ref   | i_ianswer_iaskid          | i_ianswer_iaskid | 4       | bbs.a.id |    8 | Using where                     |
+----+-------------+-------+-------+---------------------------+------------------+---------+----------+------+---------------------------------+
3 rows in set (0.00 sec)

表结构如下:

mysql> show create table users;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Table | Create Table
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| users | CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `email` varchar(128) NOT NULL,
  `password` varchar(32) NOT NULL,
  `screen_name` varchar(64) DEFAULT NULL,
  `reputation` int(10) unsigned NOT NULL DEFAULT '0',
  `imtype` varchar(1) DEFAULT '0' COMMENT '0--email,1--gtalk,2--msn',
  `last_check` datetime DEFAULT NULL,
  `robotno` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u_users_email` (`email`),
  UNIQUE KEY `u_users_screen_name` (`screen_name`),
  KEY `i_users_lastcheck` (`last_check`),
  KEY `i_users_imtype_robotno` (`imtype`,`robotno`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 row in set (0.02 sec)

mysql> show create table iask;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Table | Create Table
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| iask  | CREATE TABLE `iask` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(10) unsigned NOT NULL,
  `title` varchar(250) NOT NULL,
  `body` text,
  `tags` varchar(100) NOT NULL,
  `views` int(10) unsigned DEFAULT '0',
  `votes` int(10) unsigned DEFAULT '0',
  `answer_id` int(10) unsigned DEFAULT NULL,
  `created` datetime NOT NULL,
  `keywords` text,
  PRIMARY KEY (`id`),
  KEY `i_iask_uid` (`uid`),
  FULLTEXT KEY `keywords` (`keywords`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 row in set (0.00 sec)

mysql> show create table ianswer;
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                                                                                                                                                                                                                                                                                 |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ianswer | CREATE TABLE `ianswer` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `iaskid` int(10) unsigned NOT NULL,
  `uid` int(10) unsigned DEFAULT NULL,
  `body` text,
  `votes` int(10) unsigned DEFAULT '0',
  `created` datetime NOT NULL,
  `anonymous` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `i_ianswer_iaskid` (`iaskid`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 |
+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

如果您要问如何使第一个查询像第二个查询一样使用索引,我怀疑这是因为表中没有足够的行来证明两个索引查找的合理性。 全表扫描的行数为17行,因此它认为仅旋转查找两个id的行会更快。 如果您担心,可以尝试填充表以查看它是否仍选择全表扫描。

暂无
暂无

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

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