¿Es posible hacer que InnoDB use índices iguales a MyISAM en lugar del índice agrupado debido a la limitación de RAM mientras se beneficia de su rendimiento de concurrencia?
El gen_clust_index (índice agrupado) debajo del capó de InnoDB aloja entradas de claves primarias junto con rowids. Lo interesante sobre el uso de gen_clust_index es el hecho de que cualquier índice no único que cree siempre tendrá un rowid correspondiente para el gen_clust_index de una tabla. Por lo tanto, siempre hay búsquedas de doble índice, una para el índice secundario y otra para el gen_clust_index.
Cualquier intento de mejorar el diseño de una tabla o clave primaria se anula debido al gen_clust_index, o al menos resultados marginales en el mejor de los casos.
EJEMPLO
Algunas personas intentan ordenar un MyISAM en el orden PRIMARY KEY. De acuerdo con MySQL Database Design and Tuning, página 236, párrafo 7, bajo el subtítulo "Almacenamiento de una tabla en orden de índice":
Si con frecuencia recupera grandes rangos de datos indexados de una tabla o ordena los resultados de manera consistente en la misma clave de índice, puede considerar ejecutar myisamchk con la opción --sort-records. Al hacerlo, dígale a MySQL que ordene los datos de la tabla en el mismo orden físico que el índice, y puede ayudar a acelerar este tipo de operaciones. Alternativamente, puede combinar la instrucción ALTER TABLE con una opción ORDER BY de una columna en particular para lograr los mismos resultados.
Por supuesto, esto funciona y funciona de manera efectiva para MyISAM . Puede realizar ALTER TABLE ... ORDER BY col1, col2, ..., coln contra InnoDB donde las columnas pueden ser o no las de la CLAVE PRIMARIA. Esto no producirá resultados más rápidos para InnoDB porque ... eso es correcto ... debe consultar gen_clust_index cada vez.
Algunas personas pueden hacer que el formato de fila de la tabla se FIJE usando ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;
y pueden obtener un aumento del 20% en el rendimiento de lectura sin ningún otro cambio. Esto funciona y funciona de manera efectiva para MyISAM . Esto no producirá resultados más rápidos para InnoDB porque ... eso es correcto ... debe consultar gen_clust_index cada vez.
Puede realizar lo siguiente en una tabla InnoDB llamada mydb.mytb:
CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;
Esto pondrá la tabla en orden rowid en gen_clust_index. Esto puede producir resultados marginales para InnoDB en el mejor de los casos porque ... así es ... debe consultar el gen_clust_index cada vez.
Ahora, pongámonos un poco ridículos. Hay una interfaz NoSQL para consultar (solo SELECCIONAR) MyISAM e InnoDB llamada interfaz HandlerSocket (anteriormente llamada HANLDER) . Esto le da acceso a datos que le permiten omitir todos los protocolos SQL, ACID y MVCC . Aunque es posible, en mi humilde opinión, demasiado complicado para el código y mantener. AFAIK no hay nada impreso que indique si la interfaz HandlerSocket interactúa con gen_clust_index o no.
En resumen, hay muchas maneras de pelar un gato. En este caso, no puede obtener el gato (gen_clust_index). Supongo que es por eso que MyISAM continúa existiendo por su rendimiento de lectura, su flexibilidad en el orden de las tablas, el formato de las filas de las tablas y las herramientas que lo respaldan. InnoDB seguirá diseñado en torno a su naturaleza compatible con ACID hasta que un alma valiente tome el código fuente de InnoDB y lo transforme en algo que tenga lo mejor de MyISAM e InnoDB .
El índice agrupado es quizás la razón del rendimiento de concurrencia de InnoDB en las unidades de giro tradicionales.
Acceder a una fila a través del índice agrupado es rápido porque los datos de la fila están en la misma página donde conduce la búsqueda del índice. Si una tabla es grande, la arquitectura de índice agrupado a menudo guarda una operación de E / S de disco en comparación con las organizaciones de almacenamiento que almacenan datos de fila utilizando una página diferente del registro de índice. (Por ejemplo, MyISAM usa un archivo para filas de datos y otro para registros de índice).
La E / S de disco es costosa. Por lo tanto, reducir eso es un gran beneficio para mejorar la concurrencia.
Si la E / S de disco comienza a volverse más barata y menos cuellos de botella (por ejemplo, a medida que la tecnología SSD se vuelve más estable), Oracle podría decidir cambiar la forma en que funcionan los índices de InnoDB. Es más probable que permanezca igual, porque la misma tecnología hará que 'la limitación de RAM' sea un problema menor.
Respuesta corta: no.
InnoDB se agrupa a través de la clave primaria y, en ausencia de una clave primaria, elige el primer índice único. En ausencia de un índice único, crea una clave oculta de 6 bytes para la agrupación.
Cuando tiene la clave oculta de 6 bytes, cualquier índice secundario hace referencia a esta clave, en lugar de punteros exactos a ubicaciones de fila (como en MyISAM), por lo que termina con un recorrido de clave secundaria, y luego un recorrido de clave principal para encontrar sus registros .
Para extrapolar un poco de su pregunta, supongo que le preocupa que la memoria encaje con un árbol, porque para buscar de manera eficiente, todos los nodos raíz deben estar en la memoria, ya que siempre tiene que recorrer este camino para encontrar sus páginas de hoja.
Esto es cierto, pero un consuelo es que las bases de datos comerciales intentan hacer que sus árboles sean lo más gordos posible, en lugar de profundos. Intente ejecutar xtrabackup --stats en sus datos para ver. Por ejemplo:
<INDEX STATISTICS>
table: test/table1, index: PRIMARY, space id: 12, root page 3
estimated statistics in dictionary:
key vals: 25265338, leaf pages 497839, size pages 498304
real statistics:
level 2 pages: pages=1, data=5395 bytes, data/pages=32%
level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%
Había 497839 páginas de hoja (~ 8GB), pero solo 416 páginas arriba (6.5MB). He ejecutado este comando varias veces en datos de producción, y siempre me sorprende cuando tengo millones de billones de registros, y solo niveles de 1 a 3 páginas + páginas de hoja.