MySQL улучшение производительности запроса, WHERE целочисленное условие перед строковым условием - PullRequest
0 голосов
/ 25 марта 2020

Предположим, у меня есть MySQL база данных под именем records. Схема таблицы будет выглядеть следующим образом, где id является ключом индекса, а url уникален:

id BINGINT(20) UNSIGNED AUTO_INCREMENT
num_chars SMALLINT(4) UNSIGNED
url VARCHAR(1000) UNIQUE

Это будет представление данных таблицы, в основном:

-------------------------------------------
| id | num_chars |         url            |
-------------------------------------------
|  1 |    22     | https://www.google.com |
|  2 |    17     | https://yahoo.com      |
|  3 |    16     | https://bing.com       |
-------------------------------------------

num_chars - это количество символов в URL.

У меня такой вопрос, учитывая тот факт, что эта таблица, вероятно, будет содержать несколько миллионов записей: есть ли улучшение производительности этого запроса:

SELECT * FROM records WHERE num_chars = 17 AND url = 'https://yahoo.com';

Над этим:

SELECT * FROM records WHERE url = 'https://yahoo.com';

Я знаю, что целочисленные запросы более эффективны, чем строковые (поправьте меня, если я ошибаюсь), поэтому мне интересно, будет ли фильтрация по num_chars до url будет означать повышение эффективности.

Кстати, преимущество в этом случае заключается в том, что я могу легко вычислить num_chars из url перед выполнением запроса MySQL, используя PHP, Java, Python, et c.

Ответы [ 3 ]

1 голос
/ 25 марта 2020

У вас есть индекс unique на URL. Таким образом, оба запроса будут использовать этот индекс.

Добавление дополнительной проверки длины не ускорит запрос. Для проверки длины будут очень, очень, очень маленькие дополнительные издержки, но это несущественно.

Если у вас есть уникальный индекс, нет необходимости добавлять дополнительные проверки.

Примечание. Преимущество целочисленного сравнения перед сравнением строк возникает, когда вам не нужно сравнивать строки. В этом случае вам нужно выполнить сравнение строк.

Может быть крошечный выигрыш, если вы хэшируете строку в целое число и сравниваете ее перед сравнением строки.

0 голосов
/ 25 марта 2020

Есть ли улучшение производительности?

Ответ зависит от двух факторов:

  1. Селективность из num_chars колонка. Если большая часть ваших данных поступает из нескольких разных источников: таких как укороченные URL-адреса, ссылки на продукты Amazon и т. Д. c - на самом деле в любой системе, где у вас относительно небольшое количество возможных длин, - добавьте, что условие num_chars=17 все еще выполняется чтобы сопоставить много строк и на самом деле не фильтровать вещи много.
  2. Выбор index для таблицы. Индекс на url напрямую, без других индексов, вероятно, сделает это условие превосходящим условие num_chars независимо от селективности. Тем не менее, размещение num_chars и url в одном индексе в указанном порядке может быть полезным для использования дополнительного поля, даже при низкой селективности.

Но помните: база данных продавцы не дураки. Они посвящают много усилий поиску способов оптимизации запросов. Есть хорошие шансы, что движок уже может делать подобные вещи за кулисами. Лучшее, что вы можете сделать, - это сгенерировать некоторые примерные данные в таблице и протестировать их, чтобы знать, что в действительности произойдет.

Наконец, если вы действительно хотите это сделать, рассмотрите возможность сделать его Генерируемым столбцом. .

0 голосов
/ 25 марта 2020

Без определения соответствующего индекса оба эти запроса будут отстой.

На самом деле, целочисленные запросы более эффективны, чем текстовые; мы можем продемонстрировать быстро базирующиеся текстовые запросы и ледяные целочисленные запросы. (По крайней мере, в данном случае это не так, чтобы иметь какое-либо значение.)

Важно то, что имеет значение для больших наборов, так это эффективное использование доступного индекса.


При наличии нескольких миллионов строк нам необходимо рассмотреть распределение значений num_chars для выбросов, где имеется всего пара десятков строк, и поиск по индексу на num_chars будет быстрым. Но для больших наборов нам все еще нужно оценить url, чтобы увидеть, соответствует ли он.


Я бы просто создал индекс покрытия для запроса:

CREATE UNIQUE INDEX mytable_ix1 ON mytable (url, num_chars, id) ;

Затем запустите любой запрос, который вы хотите; мы ожидаем того же плана выполнения, поэтому производительность будет одинаковой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...