简单的mysql查询工作比嵌套选择慢

时间:2013-01-11 09:53:59

标签: mysql indexing nested

我在一张桌子上做一个简单的选择。

CREATE TABLE `book` (
 `Book_Id` int(10) NOT NULL AUTO_INCREMENT,
 `Book_Name` varchar(100) COLLATE utf8_turkish_ci DEFAULT NULL ,
 `Book_Active` bit(1) NOT NULL DEFAULT b'1' ,
 `Author_Id` int(11) NOT NULL,
 PRIMARY KEY (`Book_Id`),
 KEY `FK_Author` (`Author_Id`),
 CONSTRAINT `FK_Author` FOREIGN KEY (`Author_Id`) REFERENCES `author` (`Author_Id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5947698 DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci ROW_FORMAT=COMPACT

表格:预订


Book_Id(INTEGER 10)| Book_Name(VARCHAR 100)| Author_Id(INTEGER 10)| Book_Active(布尔)

我有三列索引:Book_Id(PRIMARY键),Author_Id(FK),Book_Active。

第一次查询:

SELECT * FROM book WHERE Author_Id = 1 AND Book_Active = 1

EXPLAIN : 
id  select_type table   type    possible_keys                   key         key_len ref     rows    Extra
1   SIMPLE      book    ref     FK_Author,index_Book_Active     FK_Author   4       const   4488510 Using where

第二个查询:

SELECT b.* FROM book b 
WHERE Book_Active=1 
AND Book_Id IN (SELECT Book_Id FROM book WHERE Author_Id=1)
EXPLAIN :
id  select_type         table   type            possible_keys       key                 key_len ref     rows    Extra
1   PRIMARY             book    ref             index_Book_Active   index_Book_Active   1       const   9369399 Using where
2   DEPENDENT SUBQUERY  book    unique_subquery PRIMARY,FK_Author   PRIMARY             4       func    1       Using where

数据统计数据如下:

16.8 million books 
10.5 million Book_Active=true
6.3 million Book_Active = false

Author_Id=1

2.4 million Book_Active=false
5000 Book_Active=true 

第一个查询需要 6.7 秒。第二个查询需要 0.0002

造成这种巨大差异的原因是什么?使用嵌套的选择查询是正确的吗?

编辑:添加“sql explain”

1 个答案:

答案 0 :(得分:2)

在第一种情况下:MySQL使用FK_Author索引(这给了我们~4.5M行),然后它必须匹配Book_Active = 1条件的每一行 - 这里不能使用索引。

第二种情况:InnoDB隐式adds每个索引的主键。因此,当MySQL执行此部分时:SELECT book.* FROM book WHERE Book_Active=1它从索引中获得Book_Id。然后,对于子查询,它必须与Book_Id匹配Author_Id; Author_Id是常量,是索引的前缀;隐式包含的主键可以与来自Book_Active索引的隐式主键进行匹配。在您的情况下,交叉两个索引比使用索引检索4.5M行并按顺序扫描它们更快。