Блог Статьи

Индексы и немного хитрой математики

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

Нередко, разница в скорости бывает не столь громадной, как этого хотелось бы (допустим, запросы вместо 1 секунды шикарным образом стали выполнятся всего 0,001 секунду). Так, частенько после добавления индекса sql-запрос может выполняться всего на 0,02 секунды быстрее (а то и того меньше).

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

Вначале немного интересных фактов.

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

2. База данных может в 1 секунду проверять лишь ограниченное количество записей.

3. Полный перебор всех записей таблицы обычно сказывается лавинообразно. Приведу жизненный пример. Допустим, у вас есть таблица «пользователи» (100 записей) и есть таблица «История действий» (1000 записей). Задача в том, что для неких 10 пользователей необходимо выдать их всю историю действий. Как вы помните из предыдущей статьи, без индексов базе данных необходимо проверять абсолютно все записи. Таким образом, для каждого пользователя базе данных придется полностью сканировать таблицу истории. То есть 10 * 1000 = 10 000 проверок. Если же количество действий увеличится с 1000 до 2000, то разница будет составлять не 1000 проверок, а целых 10 000 проверок, так как 10 * 2000 = 20 000.

4. В один момент времени сайт может открывать несколько пользователей.

5. Sql-запросы выполняются для пользователя последовательно. То есть вначале получаются одни данные, затем от них зависимые и так далее.

6. Когда несколько пользователей открывают веб-сайт, то их процессы выполняются параллельно. Это означает, что легко может сложиться ситуация, что база данных будет выполнять sql-запросы в следующем порядке: 1-й запрос 1-го пользователя, 1-й запрос 2-го пользователя, 1-й запрос 3-го пользователя, 2-й запрос 1-го пользователя, 2-й запрос 2-го пользователя, 2-й запрос 3-го пользователя и так далее. А не в том порядке, что вначале выполнятся все запросы 1-го пользователя, затем все запросы 2-го и так далее.

Есть и другие моменты, но для примера этих более чем достаточно.

Составим простые формулы:

[количество записей] = [среднее количество проверенных записей в 1 запросе] * [количество запросов] * [количество пользователей]

[затраченное время] = [количество записей] / [максимум записей в 1 секунду]

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

Допустим, в 1 секунду база данных может проверить 100 000 строк. Считаем, что каждый запрос проверяет примерно 500 строк (что соответствует 500  / 100 000 = 5 / 1000 = 0,005 секундам), так как индексы в базе не построены. В один момент времени сайт просматривает 1 человек. Запросов для генерации страницы требуется всего 100.

Итого, получаем, что 500 * 100 * 1 = 50 000. То есть, сайт в 1 секунду может открыть всего 2 человека. Если же сайт будет открывать 3 человека, то, скорее всего, им всем придется ждать в 1,5 раза больше времени (то есть 1,5 секунды  50 000 * 3 / 100 000 = 1,5), так как sql-запросов не один, а сотни, каждый из которых выполняется последовательно для человека (данные получаются последовательно и без всех данных страница не отобразится), но параллельно для всех пользователей (так как для каждого пользователя выполняется отдельный процесс).

Несложно догадаться, что увеличение пользователей или числа записей в таблицах (например, увеличили количество товара и теперь вместо 500 среднее стало 600) может существенно сказываться. Что же говорить о том, если вы установите еще какие-то модули и «вкусняшки» к себе в веб-сайт (интернет-магазин), увеличивающие количество sql-запросов.

А теперь, давайте подсчитаем что будет, если в среднем все построенные индексы позволили снизить время выполнения с 0,005 до 0,003 секунд (с 500 проверок до 300).

Получим — 300 * 100 * 1 = 30 000. Таким образом, теперь, в 1 секунду сайт может открыть не 2 человека, а 3. Кроме того, если количество записей увеличится или же количество модулей с их sql-запросами, то это не так сильно скажется на общей производительности веб-сайта или интернет-магазина.

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