I had a similar problem and after reading this question I made this plugin (adapted for your question).
Once installed it makes an admin menu under Users called Bulk User Delete when you go to this page, it deletes the users in batches, 20 at a time as per your sql query (my original query was slightly different).
You can make the batches smaller or bigger but this allows you to delete many users without server timeout, it may take a few minutes for lots of spam sign ups.
It uses jquery to reload the page after each batch is processed (this could be done with ajax I guess but I need something quickly).
Maybe someone else will find this helpful, you'll most likely need to adapt the sql query to your situation.
<?php
/*
Plugin Name: Bulk Delete Spam Users
Description: Delete the spam sign ups
Version: 0.1
Author: Steven
Text Domain: bulk-delete-spam-users
*/
add_action('admin_menu', 'my_users_menu');
function my_users_menu() {
add_users_page('Bulk User Delete', 'Bulk User Delete', 'read', 'bulk-user-delete', 'active_users_nodel');
}
function active_users_nodel() {
global $wpdb;
$result = array();
$result = $wpdb->get_results('
SELECT wp_users.id, wp_users.user_login FROM wp_users
INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id
WHERE meta_key = "wp_capabilities"
AND meta_value LIKE "%subscriber%"
');
$users = $result;
$i = 0;
echo '<div class="bud-box">';
$users_remain = $users ? 'true' : 'false';
$current_user = wp_get_current_user();
echo '<strong>Orphaned content will be reassigned to:</strong><br />';
echo 'Username: ' . $current_user->user_login . '<br />';
echo 'User ID: ' . $current_user->ID . '<br />';
<h3>currently deleting...</h3>
foreach($users as $user) {
$i++;
if($i < 20) {
wp_delete_user( $user->ID, $current_user->ID );
var_dump($user->user_login);
}
}
echo '</div>';
?>
<script>
(function($){
$(document).ready(function(){
var uremain = <?php echo $users_remain; ?>;
if( uremain == true){
location.reload();
}
});
})(jQuery);
</script>
<?php } ?>
DELETE ... FROM ... INNER JOIN... ON... LIMIT 3000
– josh Nov 2 '14 at 4:00mysql> delete wp_users, wp_usermeta FROM wp_users INNER JOIN wp_usermeta ON wp_users.ID = wp_usermeta.user_id WHERE meta_key = 'wp_capabilities' AND meta_value LIKE '%subscriber%';
Query OK, 475666 rows affected (9,26 sec)
it's very fast with thousands of subscribers, anyway :) – strangeman Feb 10 '16 at 7:10