sql >> Base de Datos >  >> RDS >> Mysql

Compatibilidad nativa con JSON en MYSQL 5.7:¿cuáles son las ventajas y desventajas del tipo de datos JSON en MYSQL?

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

El uso de una columna dentro de una expresión o función como esta arruina cualquier posibilidad de que la consulta use un índice para ayudar a optimizar la consulta. La consulta que se muestra arriba se ve obligada a hacer un escaneo de tabla.

La afirmación sobre el "acceso eficiente" es engañosa. Significa que después de que la consulta examina una fila con un documento JSON, puede extraer un campo sin tener que analizar el texto de la sintaxis JSON. Pero aún se necesita un escaneo de tabla para buscar filas. En otras palabras, la consulta debe examinar cada fila.

Por analogía, si estoy buscando en una guía telefónica a personas con el nombre de pila "Bill", todavía tengo que leer cada página de la guía telefónica, incluso si los nombres se han resaltado para que sea un poco más rápido encontrarlos.

MySQL 5.7 le permite definir una columna virtual en la tabla y luego crear un índice en la columna virtual.

ALTER TABLE t1
  ADD COLUMN series AS (JSON_EXTRACT(data, '$.series')),
  ADD INDEX (series);

Luego, si consulta la columna virtual, puede usar el índice y evitar el escaneo de la tabla.

SELECT * FROM t1
WHERE series IN ...

Esto es bueno, pero pierde el sentido de usar JSON. La parte atractiva de usar JSON es que le permite agregar nuevos atributos sin tener que hacer ALTER TABLE. Pero resulta que tiene que definir una columna adicional (virtual) de todos modos, si desea buscar campos JSON con la ayuda de un índice.

Pero no tiene que definir columnas e índices virtuales para cada campo en el documento JSON, solo aquellos que desea buscar u ordenar. Podría haber otros atributos en el JSON que solo necesita extraer en la lista de selección como los siguientes:

SELECT JSON_EXTRACT(data, '$.series') AS series FROM t1
WHERE <other conditions>

Generalmente diría que esta es la mejor manera de usar JSON en MySQL. Solo en la lista de selección.

Cuando hace referencia a columnas en otras cláusulas (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), es más eficiente usar columnas convencionales, no campos dentro de documentos JSON.

Presenté una charla llamada Cómo usar JSON en MySQL Incorrecto en la conferencia Percona Live en abril de 2018. Actualizaré y repetiré la charla en Oracle Code One en el otoño.

Hay otros problemas con JSON. Por ejemplo, en mis pruebas, requirió 2 o 3 veces más espacio de almacenamiento para documentos JSON en comparación con las columnas convencionales que almacenan los mismos datos.

MySQL está promocionando agresivamente sus nuevas capacidades JSON, en gran parte para disuadir a las personas de migrar a MongoDB. Pero el almacenamiento de datos orientado a documentos como MongoDB es fundamentalmente una forma no relacional de organizar datos. Es diferente de relacional. No digo que uno sea mejor que el otro, es solo una técnica diferente, adecuada para diferentes tipos de consultas.

Debe elegir usar JSON cuando JSON hace que sus consultas sean más eficientes.

No elija una tecnología solo porque es nueva o por moda.

Editar:se supone que la implementación de la columna virtual en MySQL usa el índice si su cláusula WHERE usa exactamente la misma expresión que la definición de la columna virtual. Es decir, lo siguiente debería use el índice en la columna virtual, ya que la columna virtual se define AS (JSON_EXTRACT(data,"$.series"))

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

Excepto que, al probar esta característica, descubrí que NO funciona por alguna razón si la expresión es una función de extracción JSON. Funciona para otros tipos de expresiones, pero no para funciones JSON. ACTUALIZACIÓN:al parecer, esto funciona, finalmente, en MySQL 5.7.33.