Mysql - производительность запросов - PullRequest
0 голосов
/ 27 декабря 2018

У меня нет данных в моей таблице MySQL, поэтому я не могу проверить, какой оператор SQL будет быстрее.

У меня есть таблица с столбцами: ID |user1 |user2 |Таблица будет иметь около 1 миллиона записей, и мне нужно выбрать id_user (int) из столбца user1 или user2.

Первый запрос:

SELECT `id`, `data` FROM `table` WHERE `user1` = :id_user OR `user2` = :id_user

или второй запрос:

SELECT `id`, `data` FROM `table` WHERE concat(user1, '/' user2) LIKE '%:id_user%'

Какой запрос выберет данные быстрее?

Ответы [ 4 ]

0 голосов
/ 27 декабря 2018

Как уже указывалось;ни один из ваших запросов не будет эффективным.Вот обходной путь:

( SELECT `id`, `data` FROM `table` WHERE `user1` = :id_user )
UNION DISTINCT
( SELECT `id`, `data` FROM `table` WHERE `user2` = :id_user )

и имеют следующие индексы:

INDEX(user1)
INDEX(user2)

Таким образом, обработка будет очень быстро выполнять каждый SELECT, затем объединитсяони используют UNION.

Обратите внимание, далее, что если не будет перекрытий (или вам все равно), то быстрее использовать UNION ALL.Говоря UNION DISTINCT выводит результат комбинированных выборов.

Подробнее при индексировании.

0 голосов
/ 27 декабря 2018

Вы можете предварительно добавить «EXPLAIN» перед вашими запросами и получить больше информации о ваших запросах.Даже если у вас есть локальная база данных с небольшим количеством примеров записей внутри вашей таблицы.Он предоставит некоторую информацию об используемых индексах / ключах.

https://dev.mysql.com/doc/refman/8.0/en/using-explain.html

https://dev.mysql.com/doc/refman/8.0/en/explain-output.html

EXPLAIN SELECT `id`, `data` FROM `table` WHERE `user1` = :id_user OR `user2` = :id_user

EXPLAIN SELECT `id`, `data` FROM `table` WHERE concat(user1, '/' user2) LIKE '%:id_user%'
0 голосов
/ 27 декабря 2018

Первый запрос быстрее, конечно.Приведите id к строке, concat, ищите по строке (не по индексу) с помощью «like».Я не знаю, что может быть медленнее этого второго запроса.

0 голосов
/ 27 декабря 2018

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

Вы можете думать об этом как о «вычисленном» столбце.Чтобы оценить сравнение, БД должна «вычислить» столбец, поэтому он больше не является статическим столбцом, существующим в базе данных, а больше похож на переменную.В вашем случае вы объединяете 2 столбца и создаете псевдо столбец.Для вычисляемого столбца индекса не существует, поэтому база данных должна прочитать данные строки, выполнить вычисления и затем оценить сравнение.Если вы посмотрите на запросы, используя EXPLAIN, то увидите, что эта таблица запросов сканирует все 1 миллион строк.

Согласно комментарию, у вас должен быть индекс для user1, индекс для user2 и запросбудет очень производительным.

Я не знаю приложения, но реализация с именем столбца ('user') и итерацией (user1, user2) обычно указывает на повторяющуюся группу, которая должна была быть нормализована вотношения многие ко многим.

С такой структурой у вас не будет запроса с WHERE user1 = something OR user2 = something.

...