使用sysbench处理测试用例,我遇到了这个问题:
的MySQL> 选择 * 从 sbtest1 其中 ID = ROUND(RAND()* 10000,0);
+ ------ + -------- + --------------------------------- -------------------------------------------------- -------------------------------------- + ----------- -------------------------------------------------- +
| id | k | c | 垫|
+ ------ + -------- + --------------------------------- -------------------------------------------------- -------------------------------------- + ----------- -------------------------------------------------- +
| 179 | 499871 | 09833083632 - 34593445843 - 98203182724 - 77632394229 - 31240034691 - 22855093589 - 98577647071 - 95962909368 - 34814236148 - 76937610370 | 62233363025 - 41327474153 - 95482195752 - 11204169522 - 13131828192 |
| 1606 | 502031 | 81212399253 - 12831141664 - 41940957498 - 63947990218 - 16408477860 - 15124776228 - 42269003436 - 07293216458 - 45216889819 - 75452278174 | 25423822623 - 32136209218 - 60113604068 - 17409951653 - 00581045257 |
+ ------ + -------- + --------------------------------- -------------------------------------------------- -------------------------------------- + ----------- -------------------------------------------------- +
2排在 组(0.30秒)
我真的很惊讶。首先,最重要的是,id是主键,rand()函数应该只生成一个值。怎么回来两行?其次,为什么响应时间为0.30秒?对于主键访问而言,这似乎非常高。
进一步观察:
CREATE TABLE `sbtest1`(
`id` int(11)NOT NULL AUTO_INCREMENT,
`k` INT(11)NOT NULL DEFAULT '0' ,
`c` char(120)NOT NULL DEFAULT '',
`pad` char(60)NOT NULL DEFAULT '',
PRIMARY KEY(`id`),
KEY `k_1`(`k`)
)ENGINE = InnoDB AUTO_INCREMENT = 1000001 DEFAULT CHARSET = latin1
的MySQL> 解释 选择 * 从 sbtest1 其中 ID = ROUND(RAND()* 10000,0);
+ ---- + ------------- + --------- + ------------ + ------ + --------------- + ------ + --------- + ------ + -------- + - --------- ------------- + +
| id | select_type | 表 | 分区 | 类型| possible_keys | 关键 | key_len | ref | 行| 过滤| 额外的|
+ ---- + ------------- + --------- + ------------ + ------ + --------------- + ------ + --------- + ------ + -------- + - --------- ------------- + +
| 1 | 简单| sbtest1 | NULL | 所有 | NULL | NULL | NULL | NULL | 986400 | 10.00 | 使用 何处 |
+ ---- + ------------- + --------- + ------------ + ------ + --------------- + ------ + --------- + ------ + -------- + - --------- ------------- + +
所以它是一个主键,但MySQL不使用索引,它返回两行。这是一个错误吗?
确定性与非确定性功能
原来它根本不是一个bug。这是MySQL非常合乎逻辑的行为,但它不是我们所期望的。首先,为什么全表扫描?好吧,rand()是非确定性函数。这意味着我们不知道它将提前返回什么,实际上,这正是rand()的目的 - 返回一个随机值。在这种情况下,每次评估每行的函数并比