2009-06-13 11 views
0
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) 

Änderung der oben "in (1,2)" in "= 1" wird alles mit Index machen:wie diese Abfrage in MYSQL zu optimieren?

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) 

Tabellenstruktur wie folgt:

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> 
+0

geben Sie uns eine Tabellenstruktur, Liste der Indizes, etc. – moo

+0

OK, fertig :) – omg

Antwort

4

Wenn Sie Bei der Frage, wie die erste Abfrage einen Index wie die zweite Abfrage verwenden soll, vermute ich, dass es nicht genügend Zeilen in der Tabelle gibt, um zwei Indexnachschlage zu rechtfertigen. Die Zeilenanzahl für einen vollständigen Tabellenscan beträgt 17 Zeilen. Daher ist es der Ansicht, dass es schneller ist, nur durch die Zeilen zu blättern, wenn nach zwei IDs gesucht wird. Wenn Sie besorgt sind, könnten Sie versuchen, die Tabelle aufzufüllen, um zu sehen, ob sie immer noch einen vollständigen Tabellenscan wählt.

+0

+1 Indizes sind Overkill für Tabellen mit weniger als etwa 200 Reihen – Andomar

+0

Es stellt sich heraus, dass es richtig ist :) – omg

Verwandte Themen