Скорее всего, при миллиардах записей, id2 char(255) будет слишком велик, что бы полностью уместиться в оперативной памяти, в отличие от id1 integer, и запрос по нему станет медленнее.
Но повлияет ли это на запросы только по полю id1, который должен остаться быстрым?
Я склоняюсь к тому, что, индексы хранятся отдельно и друг на друга не влияют, но хотелось бы уточнить, т.к. в будущем,, когда в базе будет миллиарды записей, alter table, если что, будет большой проблемой.
Ну так создай базу с "миллиардом" записей и сделай замеры, в чем проблема?
Ты сейчас придумываешь узкое место, а по факту окажется, что при таблице с миллиардом записи, у тебе вообще другие узкие места будут, так что тут помогает только создание тестового окружение и его исследование. Так же может оказаться, пока ты растешь до этого миллиарда, у тебя сильно поменяют схемы данных.
Экспериментируйте. Индексы - это самостоятельные объекты в СУБД. Вы можете в любой момент добавить индексы к таблице, и в любой момент удалить. Да, будет просадка производительности на момент пересчета индекса, но на структуру хранения самой таблицы это никак не влияет, как там поживают индексы сбоку.
Вопрос не в том, как индексы "хранятся", а в том, как используются. Индексы не живут в каком-то своем собственном альтернативном пространстве. А используют ту же самую оперативную память. Следовательно, если использовать в запросе какой-то индекс, то БД будет пытаться разместить его в оперативной памяти. И в итоге всем индексам будет не хватать места.
Если есть опасение, что индекс окажется слишком большим, надо заняться такой вещью, как размышления. И задать себе вопросы:
А нужен ли нам избыточный тип CHAR? Почему бы не использовать нормальный VARCHAR?
Нужен ли нам индекс по всей длине поля, или можно проиндексировать только начало, а остальное легко найдётся перебором?
Если нужен по всей, то не сделать ли дополнительную колонку с MD5 от содержимого поля CHAR, которая будет занимать всего 16 байт, и проиндексировать уже её?