Два запроса, которые почти одинаковы, но не загружаются даже быстро

Я работаю над игрой, и я связываю автомобильный номер с пользователем, который владеет автомобилем.

Когда я выполняю первый запрос, чтобы найти владельца автомобиля, требуется ок. 1 секунда

SELECT aid FROM owned_vehicles INNER JOIN users ON users.identifier = owned_vehicles.owner WHERE vehicle LIKE '%04IBQ509%' LIMIT 1

В результате получается aid, который относится к первичному ключу пользователя, владеющего автомобилем. В таком случае

aid
11

Но когда я использую тот же запрос на другой номерной знак, загрузка данных занимает более 30 секунд (обнаружил эту проблему, когда пользователи жаловались на время загрузки и сообщение о тайм-ауте)

SELECT aid FROM owned_vehicles INNER JOIN users ON users.identifier = owned_vehicles.owner WHERE vehicle LIKE '%85RAF179%' LIMIT 1

По прошествии более 30 секунд это приводит к появлению 5475. Как такое может быть, что этой новой машине требуется намного больше времени для загрузки?

Пытаясь решить эту проблему, я выполнил эти запросы как в HeidiSQL (MySQL GUI), так и в результате странного времени выполнения.

Я попытался создать индекс колонки транспортного средства, чтобы ускорить его. Но это не имеет значения.

Кто-нибудь знает, как решить мою проблему и ускорить мой запрос? (Исключение должно длиться максимум 2 секунды)

LIMIT 1 указывает mysql останавливаться после первого совпадения. Так что вполне может быть, что 04IBQ509 находится в начале, а 85RAF179 - где-то в конце ваших данных.

Salman A 27.11.2018 13:21

Забыл упомянуть. Когда я не использую лимит, время загрузки такое же. @salman

Koen Hollander 27.11.2018 13:21

Сколько строк в таблице, содержащей регистрационный номер?

Salman A 27.11.2018 13:22

Таблица почти 40МБ

Koen Hollander 27.11.2018 13:22

Табличка автомобиля во втором примере - это именно "85RAF179"?

Cid 27.11.2018 13:26

@Cid Столбец транспортного средства представляет собой поле json с ...... табличкой: 85RAF179 ......

Koen Hollander 27.11.2018 13:35

Почему бы не использовать WHERE vehicle = "plate:85RAF179"? производительность может улучшиться

Cid 27.11.2018 13:41

..... это означает намного больше данных, чем только табличка.

Koen Hollander 27.11.2018 13:55

Может быть, пришло время изменить дизайн вашего стола? Какой смысл сохранять строку json, если у вас может быть структурированная база данных?

Cid 27.11.2018 14:05

1 секунда по-прежнему огромный для такого запроса. Я просто написал запрос с двумя соединениями и предложением where. 0,015 секунды.

Cid 27.11.2018 14:09
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
10
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы выполняете LIKE с подстановочным знаком % в начале. Это исключает использование любого индекса в столбце транспортного средства. Если вы удалите % в начале номера автомобиля, а затем добавите индекс в этот столбец, вы увидите значительно улучшенную производительность. Конечно, это меняет характер запроса, но в настоящее время вы выполняете сканирование таблицы owned_vehicles, что не будет устойчивым для запроса, который выполняется с какой-либо регулярностью в вашей игре.

После просмотра комментариев выше оказалось, что столбец вашего автомобиля на самом деле является данными JSON. Вам нужно переосмыслить способ хранения этого. Если вам нужно очень быстро запросить автомобили с регистрационным номером, вам нужно будет извлечь эту регистрацию в другой столбец, проиндексировать ее и отфильтровать по этому столбцу. Реляционная СУБД не предназначена для фильтрации на основе LIKE строки JSON. Помимо всего прочего, вы не можете быть уверены, что передаваемые вами строки не будут соответствовать другому свойству (кроме регистрации) в строке JSON.

Другие вопросы по теме