sql >> Database >  >> RDS >> Mysql

Native JSON-ondersteuning in MYSQL 5.7:wat zijn de voor- en nadelen van het JSON-gegevenstype in MYSQL?

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

Het gebruik van een kolom in een expressie of functie als deze verpest elke kans dat de query een index gebruikt om de query te optimaliseren. De bovenstaande query wordt gedwongen om een ​​tabelscan uit te voeren.

De bewering over "efficiënte toegang" is misleidend. Het betekent dat nadat de query een rij met een JSON-document heeft onderzocht, het een veld kan extraheren zonder de tekst van de JSON-syntaxis te hoeven ontleden. Maar er is nog steeds een tabelscan nodig om naar rijen te zoeken. Met andere woorden, de query moet elke rij onderzoeken.

Naar analogie, als ik in een telefoonboek zoek naar mensen met de voornaam "Bill", moet ik nog steeds elke pagina in het telefoonboek lezen, zelfs als de voornamen zijn gemarkeerd om ze iets sneller te kunnen herkennen.

Met MySQL 5.7 kunt u een virtuele kolom in de tabel definiëren en vervolgens een index maken op de virtuele kolom.

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

Als u vervolgens de virtuele kolom opvraagt, kan deze de index gebruiken en de tabelscan vermijden.

SELECT * FROM t1
WHERE series IN ...

Dit is leuk, maar het mist een beetje het punt van het gebruik van JSON. Het aantrekkelijke van het gebruik van JSON is dat je nieuwe attributen kunt toevoegen zonder ALTER TABLE te hoeven doen. Maar het blijkt dat je toch een extra (virtuele) kolom moet definiëren, als je met behulp van een index in JSON-velden wilt zoeken.

Maar u hoeft geen virtuele kolommen en indexen te definiëren voor elke veld in het JSON-document—alleen degene waarop u wilt zoeken of sorteren. Er kunnen andere attributen in de JSON zijn die u alleen in de selectielijst hoeft te extraheren, zoals de volgende:

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

Over het algemeen zou ik zeggen dat dit de beste manier is om JSON in MySQL te gebruiken. Alleen in de selectielijst.

Wanneer u verwijst naar kolommen in andere clausules (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), is het efficiënter om conventionele kolommen te gebruiken, geen velden in JSON-documenten.

Ik presenteerde een lezing genaamd Hoe JSON te gebruiken in MySQL Verkeerd op de Percona Live-conferentie in april 2018. Ik zal de lezing bijwerken en herhalen op Oracle Code One in de herfst.

Er zijn andere problemen met JSON. In mijn tests had het bijvoorbeeld 2-3 keer zoveel opslagruimte nodig voor JSON-documenten in vergelijking met conventionele kolommen die dezelfde gegevens opslaan.

MySQL promoot hun nieuwe JSON-mogelijkheden agressief, voornamelijk om mensen ervan te weerhouden te migreren naar MongoDB. Maar documentgeoriënteerde gegevensopslag zoals MongoDB is in wezen een niet-relationele manier om gegevens te organiseren. Het is anders dan relationeel. Ik zeg niet dat de ene beter is dan de andere, het is gewoon een andere techniek, geschikt voor verschillende soorten zoekopdrachten.

U moet ervoor kiezen om JSON te gebruiken wanneer JSON uw zoekopdrachten efficiënter maakt.

Kies een technologie niet alleen omdat deze nieuw is of omwille van de mode.

Bewerken:de implementatie van de virtuele kolom in MySQL wordt verondersteld de index te gebruiken als uw WHERE-clausule exact dezelfde uitdrukking gebruikt als de definitie van de virtuele kolom. Dat wil zeggen, het volgende moet gebruik de index op de virtuele kolom, aangezien de virtuele kolom is gedefinieerd AS (JSON_EXTRACT(data,"$.series"))

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

Behalve dat ik door het testen van deze functie heb ontdekt dat het om de een of andere reden NIET werkt als de expressie een JSON-extractiefunctie is. Het werkt voor andere soorten expressies, alleen niet voor JSON-functies. UPDATE:dit werkt naar verluidt eindelijk in MySQL 5.7.33.



  1. Top 5 feiten voor het zoeken en vervangen van SQL-teksten in SQL Server met de REPLACE-functie

  2. Hoe de UCASE()-functie werkt in MySQL

  3. MYSQL Selecteer MAX Date in een join-instructie

  4. Selecteer de eerste rij van elke groep in sql