3

単一のテーブルから単純な選択を行っています。

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 (整数 10) | Book_Active (ブール値)

Book_Id (PRIMARY key) 、 Author_Id (FK) 、 Book_Active の 3 つの列にインデックスがあります。

最初のクエリ:

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

2 番目のクエリ:

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秒かかります。2 番目のクエリには0.0002秒かかります

この大きな違いの原因は何ですか?ネストされた選択クエリを使用するのは正しいことですか?

編集:「SQLの説明」を追加

4

1 に答える 1

2

最初のケース: MySQL はFK_Authorインデックスを使用します (これにより、最大 450 万行が得られます)。すべての行をBook_Active = 1条件に一致させる必要があります — ここではインデックスを使用できません。

2 番目のケース: InnoDBはすべてのインデックスに主キーを暗黙的に追加します。したがって、MySQL がこの部分を実行するSELECT book.* FROM book WHERE Book_Active=1Book_Id、インデックスから取得されます。次に、サブクエリの場合、 ; と一致Book_Idする必要があります。は定数であり、インデックスのプレフィックスです。暗黙的に含まれる主キーは、インデックスの暗黙的な主キーと照合できます。あなたの場合、インデックスを使用して 4.5M 行を取得し、それらを順次スキャンするよりも、2 つのインデックスを交差させる方が高速です。Author_IdAuthor_IdBook_Active

于 2013-01-11T11:01:49.970 に答える