Cố gắng chọn một hàng ngẫu nhiên từ một bảng, dựa trên khóa chính được tự động tăng thêm không có lỗ.MySQL: Tại sao so sánh khóa chính với số được tạo ngẫu nhiên không sử dụng chỉ mục?
Giản đồ bảng:
CREATE TABLE IF NOT EXISTS `testTable` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`data` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
INSERT INTO `testTable` (`id`, `data`) VALUES
(1, 'hello'),
(2, 'world'),
(3, 'new'),
(4, 'data'),
(5, 'more and more'),
(6, 'data '),
(7, 'more rows here'),
(8, 'most rows here'),
(9, 'testing'),
(10,'last');
Queries:
1/explain select * from testTable where id = ceil(Rand()*10) limit 1 ;
http://sqlfiddle.com/#!2/6e2b1/1
Kết quả:
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA |
--------------------------------------------------------------------------------------------------------
| 1 | SIMPLE | testTable | ALL | (null) | (null) | (null) | (null) | 10 | Using where |
2/explain select * from testTable where id = 7 limit 1 ;
http://sqlfiddle.com/#!2/6e2b1/2
Kết quả:
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA |
---------------------------------------------------------------------------------------------------
| 1 | SIMPLE | testTable | const | PRIMARY | PRIMARY | 4 | const | 1 | |
Tại sao truy vấn # 1 không sử dụng các chỉ số, khi ceil(rand()*10)
lý tưởng nên đánh giá để một hằng số mà sau đó có thể được so sánh với khóa chính? Không nên trình tối ưu hóa hoạt động theo cách đó? Hoặc tôi thiếu một cái gì đó hiển nhiên ở đây.
sử dụng các hàm trong điều kiện WHERE (như ceil/rand) khiến hệ thống tìm nạp tất cả các hàng trước để có thể so sánh kết quả với mọi kết quả của hàm đó. Bạn sẽ được tốt hơn bằng cách sử dụng một "bên ngoài" chọn lấy giá trị số nguyên ngẫu nhiên và sau đó sử dụng này để lấy khóa chính của bạn. – Najzero