Обычно (есть и другие варианты) индекс базы данных - это B-дерево, что означает, что вы можете выполнять сканирование диапазона (включая сканирования на равенство).
Условие app_user_id % 10 = 0
не может быть оценено с помощью одного сканирования диапазона, поэтому база данных, вероятно, не будет использовать индекс.
Возможно, он решит использовать индекс по-другому, а именно для полного сканирования: чтение всей таблицы занимает больше времени, чем простое чтение всего индекса. С другой стороны, после прочтения индекса вы все равно можете вернуться к таблице, поэтому общая стоимость может оказаться выше.
Решать должен оптимизатор запросов к базе данных.
Несколько примеров:
select app_user_id from t where app_user_id % 10 = 0
Здесь вам не нужна таблица, все необходимые данные находятся в индексе. Скорее всего, база данных выполнит полное сканирование индекса.
select count(*) from t where app_user_id % 10 = 0
То же самое. Полное сканирование индекса.
select count(*) from t
Только если app_user_id имеет значение NOT NULL, это можно сделать с помощью индекса (поскольку данные NULL отсутствуют в индексе, по крайней мере, в Oracle, по крайней мере, в индексах с одним столбцом, ваша база данных может обрабатывать это по-другому).
Некоторым базам данных для этого не требуется таблица доступа или индекс, они поддерживают количество строк в метаданных.
select * from t where app_user_id = 5
Это классический сценарий для индекса. База данных может просмотреть небольшой раздел дерева индексов, извлечь небольшое (только один, если это был уникальный или первичный индекс) количество строк и выбрать их выборочно из таблицы.
select * from t where app_user_id between 5 and 10
Еще один классический индексный кейс. Сканирование диапазона в дереве возвращает небольшое количество строк, извлекаемых из таблицы.
select * from t where app_user_id between 5 and 10 order by app_user_id
Поскольку сканирование индекса возвращает упорядоченные данные, вы даже можете получить сортировку бесплатно.
select * from t where app_user_id between 5 and 1000000000
Может быть, здесь вы не должны использовать индекс. Кажется, слишком много записей. Это тот случай, когда наличие переменных связывания, скрывающих диапазон от базы данных, может фактически нанести ущерб.
select * from t where app_user_id between 5 and 1000000000
order by app_user_id
Но здесь, поскольку сортировка была бы очень дорогой (даже занимая место на временном диске подкачки), возможно, итерация в порядке индекса хороша. Может быть.
select * from t where app_user_id % 10 = 0
Это трудно решить. Нам нужны все столбцы, поэтому в конечном итоге запрос должен касаться таблицы. Вопрос в том, стоит ли сначала пройти индекс. Запрос возвращает примерно 10% всей таблицы. Вероятно, это слишком много для того, чтобы путь доступа к индексу был эффективным. Если у оптимизатора есть основания полагать, что запрос возвращает намного меньше 10% таблицы, сканирование индекса с последующим доступом к таблице может быть полезным. То же самое, если таблица очень фрагментирована (много удаленных строк занимает место).