Хороший вопрос, хотя и задавался миллион раз.
Когда у вас выполняется запрос
SELECT * FROM users WHERE DATE(created_at) = '2024-04-14'
то СУБД должна пройти весь индекс до конца, получить каждое значение created_at, применить к нему функцию, сравнить с переданным значением, и добавить строку в результат запроса.
Когда у вас выполняется запрос
SELECT * FROM users WHERE created_at BETWEEN '2024-04-14 00:00:00' AND '2024-04-14 23:59:59'
То СУБД находит бинарным поиском первое нужное значение, потом бежит по заранее отсортированному индексу и возвращает все значения до последнего, подходящего под второе условие.