-
mysql> explain extended select count(*) from testinfo where id not in (select id from testinfo group by idtest);
-
+----+--------------------+----------+-------+---------------+------------+---------+------+------+-----------+--------------------------+
-
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
-
+----+--------------------+----------+-------+---------------+------------+---------+------+------+-----------+--------------------------+
-
| 1 | PRIMARY | testinfo | index | NULL | key_idtest | 62 | NULL | 8761 | 100.00 | Using where; Using index |
-
| 2 | DEPENDENT SUBQUERY | testinfo | index | NULL | key_idtest | 62 | NULL | 1 | 876100.00 | Using index |
-
+----+--------------------+----------+-------+---------------+------------+---------+------+------+-----------+--------------------------+
-
2 rows in set, 1 warning (0.00 sec)
表面上看都走了索引,但仔细发现filtered列为876100,这个值很大,直接影响到执行sql时扫描的行数。
-
mysql> show warnings \G
-
*************************** 1. row ***************************
-
Level: Note
-
Code: 1003
-
Message: select count(0) AS `count(*)` from `test`.`testinfo` where (not(<in_optimizer>(`test`.`testinfo`.`id`,<exists>(select `test`.`testinfo`.`id` from `test`.`testinfo` group by `test`.`testinfo`.`idtest` having (<cache>(`test`.`testinfo`.`id`) = <ref_null_helper>(`test`.`testinfo`.`id`))))))
-
1 row in set (0.00 sec)
-
可见,经过mysql优化器后,in 给转换成exists的方式,下面实际执行一次sql花了36秒
-
mysql> select count(*) from testinfo where id not in (select id from testinfo group by idtest);
-
+----------+
-
| count(*) |
-
+----------+
-
| 1059 |
-
+----------+
-
1 row in set (36.79 sec)
-
-
根据上面的执行计划,估算大概的扫描的行数为:76755121
-
mysql> select 8761*((876100*1)/100)
-
-> ;
-
+-----------------------+
-
| 8761*((876100*1)/100) |
-
+-----------------------+
-
| 76755121.0000 |
-
+-----------------------+
-
1 row in set (0.00 sec)
-
-
而实际执行扫描的行数为:50910026
-
# User@Host: root[root] @ localhost []
-
# Query_time: 36.793302 Lock_time: 0.000227 Rows_sent: 1 Rows_examined: 50910026
-
SET timestamp=1374723426;
-
select count(*) from testinfo where id not in (select id from testinfo group by idtest);