Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Natywna obsługa JSON w MYSQL 5.7:jakie są zalety i wady typu danych JSON w MYSQL?

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

Używanie kolumny w wyrażeniu lub funkcji, jak to, niweczy wszelkie szanse, że zapytanie użyje indeksu, aby pomóc zoptymalizować zapytanie. Zapytanie pokazane powyżej jest wymuszone do skanowania tabeli.

Twierdzenie o „efektywnym dostępie” jest mylące. Oznacza to, że gdy zapytanie przeanalizuje wiersz z dokumentem JSON, może wyodrębnić pole bez konieczności parsowania tekstu składni JSON. Ale nadal wymaga skanowania tabeli, aby wyszukać wiersze. Innymi słowy, zapytanie musi zbadać każdy wiersz.

Analogicznie, jeśli przeszukuję książkę telefoniczną w poszukiwaniu osób o imieniu „Bill”, nadal muszę przeczytać każdą stronę w książce telefonicznej, nawet jeśli imiona zostały podświetlone, aby nieco szybciej je dostrzec.

MySQL 5.7 umożliwia zdefiniowanie wirtualnej kolumny w tabeli, a następnie utworzenie indeksu na wirtualnej kolumnie.

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

Następnie, jeśli zapytasz o kolumnę wirtualną, może ona użyć indeksu i uniknąć skanowania tabeli.

SELECT * FROM t1
WHERE series IN ...

To miłe, ale trochę mija się z celem używania JSON. Atrakcyjną częścią korzystania z JSON jest to, że umożliwia dodawanie nowych atrybutów bez konieczności wykonywania ALTER TABLE. Ale okazuje się, że i tak musisz zdefiniować dodatkową (wirtualną) kolumnę, jeśli chcesz przeszukiwać pola JSON za pomocą indeksu.

Ale nie musisz definiować wirtualnych kolumn i indeksów dla każdego w dokumencie JSON — tylko te, które chcesz przeszukiwać lub sortować. Mogą istnieć inne atrybuty w pliku JSON, które wystarczy wyodrębnić z listy wyboru, takie jak:

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

Ogólnie powiedziałbym, że jest to najlepszy sposób na użycie JSON w MySQL. Tylko na liście wyboru.

Kiedy odwołujesz się do kolumn w innych klauzulach (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), efektywniej jest używać konwencjonalnych kolumn, a nie pól w dokumentach JSON.

Przedstawiłem wykład o nazwie Jak używać JSON w MySQL Źle na konferencji Percona Live w kwietniu 2018 r. Jesienią zaktualizuję i powtórzę przemówienie na Oracle Code One.

Są inne problemy z JSON. Na przykład w moich testach wymagało to 2-3 razy więcej miejsca na przechowywanie dokumentów JSON w porównaniu do konwencjonalnych kolumn przechowujących te same dane.

MySQL agresywnie promuje swoje nowe możliwości JSON, głównie po to, aby zniechęcić ludzi do migracji do MongoDB. Jednak przechowywanie danych zorientowane na dokumenty, takie jak MongoDB, jest zasadniczo nierelacyjnym sposobem organizowania danych. Różni się od relacji. Nie mówię, że jedno jest lepsze od drugiego, to po prostu inna technika, dostosowana do różnych typów zapytań.

Powinieneś wybrać JSON, gdy JSON sprawi, że Twoje zapytania będą bardziej wydajne.

Nie wybieraj technologii tylko dlatego, że jest nowa lub ze względu na modę.

Edycja:implementacja kolumny wirtualnej w MySQL powinna używać indeksu, jeśli klauzula WHERE używa dokładnie tego samego wyrażenia, co definicja kolumny wirtualnej. Oznacza to, że powinien użyj indeksu w kolumnie wirtualnej, ponieważ kolumna wirtualna jest zdefiniowana AS (JSON_EXTRACT(data,"$.series"))

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

Z wyjątkiem tego, że testując tę ​​funkcję, odkryłem, że z jakiegoś powodu NIE działa, jeśli wyrażenie jest funkcją wyodrębniania JSON. Działa z innymi typami wyrażeń, ale nie z funkcjami JSON. AKTUALIZACJA:to podobno wreszcie działa w MySQL 5.7.33.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak uzyskać rok z kolumny daty i godziny w MySQL?

  2. Wydajność MySQL:Indeksy MySQL/MariaDB

  3. Jaka jest różnica między utf8_general_ci a utf8_unicode_ci?

  4. Jak uzyskać rozmiar bazy danych MySQL?

  5. Jaka jest różnica między MySQL a SQL?