Intentando seleccionar una fila aleatoria de una tabla, basada en la clave primaria autoincrementada sin agujeros.MySQL: ¿Por qué la comparación de la clave principal con un número generado aleatoriamente no utiliza el índice?
El esquema de la tabla:
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');
Consultas:
1/explain select * from testTable where id = ceil(Rand()*10) limit 1 ;
http://sqlfiddle.com/#!2/6e2b1/1
Resultado:
| 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
Resultado:
| ID | SELECT_TYPE | TABLE | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA |
---------------------------------------------------------------------------------------------------
| 1 | SIMPLE | testTable | const | PRIMARY | PRIMARY | 4 | const | 1 | |
Por qué se consulta # 1 no utiliza el índice, cuando ceil(rand()*10)
debe evaluar idealmente a una constante que puede ser comparada con la clave principal? ¿No debería el optimizador funcionar de esa manera? O me estoy perdiendo algo obvio aquí.
utilizando funciones en DONDE las condiciones (como ceil/rand) hacen que el sistema busque todas las filas primero para poder comparar los resultados con cada resultado de esa función. Será mejor que utilice una selección "externa" para obtener el valor entero aleatorio y luego use esto para recuperar su clave principal. – Najzero