2012-04-15 29 views
7

Tôi có một câu hỏi rất đơn giản:truy vấn MySql đơn giản của tôi không sử dụng chỉ mục

SELECT comments.* 
    FROM comments 
    WHERE comments.imageid=46 

Và đây là bàn của tôi:

CREATE TABLE IF NOT EXISTS `comments` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `imageid` int(10) unsigned NOT NULL DEFAULT '0', 
    `uid` bigint(20) unsigned NOT NULL DEFAULT '0', 
    `content` text CHARACTER SET utf8, 
    `adate` datetime DEFAULT NULL, 
    `ip` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `ids` (`imageid`) USING BTREE, 
    KEY `dt` (`adate`) USING BTREE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ; 

Nhưng MySql không thể sử dụng chỉ mục trên truy vấn đơn giản này . đây là kết quả giải thích:

id select_type  table type possible_keys key  key_len  ref  rows filtered Extra 
1 SIMPLE comments ALL  ids  NULL NULL NULL 4 75.00 Using where 

trong khi tôi thay đổi truy vấn này, Mysql có thể sử dụng chỉ mục. Tại sao? :

SELECT comments.id 
    FROM comments 
    WHERE comments.imageid=46 

đây là giải thích:

id select_type  table type possible_keys key  key_len  ref  rows filtered Extra 
1 SIMPLE comments ref  ids  ids  4 const 4 100.00 Using index 
+0

Nó không * "Nhưng MySql ** không thể sử dụng chỉ mục" *. Đó là: "Nhưng MySql ** sẽ không ** sử dụng chỉ mục". 'Possible_keys = ids' và' key = NULL' gợi ý rằng việc sử dụng chỉ mục đã được trình tối ưu hóa kiểm tra và bị từ chối. Quét toàn bộ bảng được cho là nhanh hơn - và có thể trong trường hợp của bạn. –

Trả lời

6

Tôi đoán rằng bạn có vài dòng trong bảng 'bình luận', đây là lý do tại sao MySQL được thực hiện một đầy đủ quét bảng thay vì sử dụng chỉ mục trong truy vấn đầu tiên của bạn. Nó ước tính rằng chi phí của một bảng quét toàn bộ có thể thấp hơn so với đầu tiên phù hợp với chỉ số và sau đó tra cứu các hàng.

Trong truy vấn thứ hai của bạn đang sử dụng chỉ mục vì có thể nhận tất cả các cột của truy vấn (cột 'id') trực tiếp từ chỉ mục mà không cần tìm kiếm các hàng trong bảng sau khi so khớp chỉ mục. Đây là ý nghĩa của thông tin bổ sung "Sử dụng chỉ mục".

Hãy thử nếu với một số lượng đáng kể các hàng trong 'nhận xét' MySQL vẫn sử dụng quét toàn bộ, tôi nghĩ rằng đó sẽ là một hành vi kỳ lạ. Trong thực tế, tôi đã thử nghiệm chính xác như nhau trong một phiên bản MySQL 5.1 và nó luôn luôn sử dụng 'chỉ số' ngay cả với vài hàng.

+0

Cảm ơn người đàn ông, Bạn đã đúng! ;) – MscEliot

1

Truy vấn thứ hai là truy vấn được lập chỉ mục. Toàn bộ thông tin được yêu cầu có thể được đọc từ chỉ mục (vì khóa chính là một phần của bất kỳ chỉ mục phụ nào trong InnoDB).

Trong truy vấn đầu tiên, MySQL phải đọc các PK từ chỉ mục, sau đó đọc các hàng. Vì bảng có số lượng hàng rất nhỏ, trình tối ưu hóa quyết định sẽ nhanh hơn nếu nó đọc trực tiếp các hàng và loại bỏ các hàng không khớp với

Các vấn đề liên quan