Не кажется. Подменять raw query это крайний случай, когда нет других способов. Тем более, в вашем примере лимиты указаны неправильно - будут показываться все те же 20 постов каждый раз, на любой странице, см LIMIT: https://dev.mysql.com/doc/refman/5.7/en/select.html
А конкретнее - потому что в новый запрос не передается "paged" поэтому он всегда отображает последние 20 постов. А передавать этот параметр в этом конкретном случае особого смысла нет: в некоторых случаях будет 404я ошибка, например если значение posts_per_page в новом запросе меньше, чем в оригинальном запросе.
Задача простая: задать posts_per_page ДО выполнения основного запроса. Либо указав значение в Settings>Readings, либо используя тот же pre_get_posts (если нужно изменить только для конкретного случая, например для отображения терминов в таксономии book)
Пример для таксономии book:
add_action('pre_get_posts', 'posts_per_book_tax_page');
function posts_per_book_tax_page($query) {
if ( is_admin() || !$query->is_main_query() )
return;
if ( $query->is_tax('book') )
$query->set('posts_per_page', 20);
}
Больше про Conditional Tags (а-ля is_tax): https://codex.wordpress.org/Conditional_Tags
PS: Проверкa на is_main_query() ОБЯЗАТЕЛЬНА.
PPS: кстати, в 4.1 добавили свою функцию: the_posts_pagination
Главный вопрос: вся эта музыка с лимитом 20 постов на страницу - затевается для ВСЕХ страниц, или для конкретных? Если для конкретных - то для каких (категории, теги, иные архивы)?