#mysql #query-optimization
Вопрос:
Я пытаюсь выполнить запрос для извлечения некоторых данных JSON из таблицы MySQL, но это занимает очень много времени. Я запустил запрос, и он все еще не вернулся более чем через 1 час. К тому времени время ожидания окна терминала AWS истекло.
Вот как выглядит таблица:
mytable1
------------------ -------------- ------ ----- --------- ------- | Field | Type | Null | Key | Default | Extra | ------------------ -------------- ------ ----- --------- ------- | m_id | varchar(100) | YES | | NULL | | | t_id | int | YES | | NULL | | | timestamp | int | YES | | NULL | | | mydata | json | YES | | NULL | | ------------------ -------------- ------ ----- --------- -------
в столбце mydata содержатся данные json, подобные этому:
{ "var1": "adfsfs", "var2": "dafdafds", "abc1": { "vals": { "x1": 11, "yz": [4,3,5,5] } } }
Это и есть запрос:
select JSON_EXTRACT(mydata,'$.abc1') from mytable1 where timestamp=1627003989;
В таблице менее 90 000 строк. Каждая строка составляет всего около 1 МБ, большая часть из которых находится в поле «мои данные».
Есть только один индекс — в поле m_id.
Есть идеи, почему это занимает так много времени? Есть ли какой-то другой способ извлечь данные из этого столбца json?
Комментарии:
1. Сколько записей имеют такое значение метки времени? Сколько времени требуется, чтобы вернуться
SELECT COUNT(1) FROM mytable1 WHERE timestamp=1627003989
?2. Чуть менее 90 000 записей, так как каждая запись имеет одну временную метку, связанную с ней. Этот запрос занимает менее 0,5 секунды.
3. 1 МБ на строку-это довольно много. Это ~90 ГБ данных, плюс время, необходимое для анализа записей и извлечения нужного ключа
4. Чего я не понимаю , так это того, что даже если я не буду использовать JSON_EXTRACT и вместо этого просто скажу:
select * from mytable1 where timestamp=1627003989
, это займет целую вечность. Это даже не должно приводить к какому-либо анализу данных JSON, верно? Все, что нужно сделать, это посмотреть метку времени для совпадения и вернуть всю запись.5. Если в столбце нет индекса
timestamp
, то он должен выполнить сканирование таблицы, изучив каждую строку. Это означает удаление 90 ГБ с диска в пул буферов еще до того, как он начнет извлекать нужное поле из документов JSON. Это, вероятно, большая часть потраченного времени, гораздо более дорогостоящая, чем извлечение JSON.
Ответ №1:
Добавьте индекс в столбец метки времени.