Select random IDs from a table, using MySQLi
In the comments section, we talked about options around the DB queries.  It sounds like ORDER BY rand() may not be suitable for your use case in dealing with those execution times (which still seem odd to me given size of dataset).

So let's assume rather than look at optimizing that randomized query (again there are many good examples of this out there), or caching query results locally in some manner that you find appropriate, we are just going to look at simplifying your code, but sticking with the approach of randomizing the id's in the application.

I would suggest that you test through both sides of your if-else conditional to understand the relative completion speed of the "download all ids and shuffle" vs. the "random row retrieval" side of the conditional.  Ask yourself things like:


Do you really need both sides of this conditional?
What are the actual use cases of your application?
Are you primarily going to be grabbing one or a few rows at a time vs. grabbing entire set of id's?


This may influence your way of thinking about this section of code.  It might even, for example, prompt you to split this function with one function being called to get full result set and another function being called to get partial result set.

You may want to look at randomization approach in the data seek side of the conditional.  If you were trying to retrieve a substantial portion of (but not full) result set, you could waste a lot of time in the while loop trying to find an offset that has not already been set in the result array.

A better approach to randomization might be:

// generate array of offsets to search by getting
// $length number of random offset keys
// assume $length has already been verified to be &lt;= $count
// not shown - you might check whether sorting $target_offsets helps with access time at all
$target_offsets = array_rand(range(0, $count - 1), $length);

for ($i = 0; $i &lt; $length; i++) {
    // seek record and read into $ids array
    mysqli_data_seek($ids_r, $target_offsets[$i]);
    $id = mysqli_fetch_assoc($ids_r);
    $ids[] = $id['id'];
}


Regardless of approach here, you need to understand if at some percentage of full result set, it might be faster to retrieve full array, shuffle and slice to get the desired result vs. random row retrieval.

A few other thoughts in looking at your code:


Always strive to use meaningful variables names.


Consider these examples:

$ids_r =&gt; $id_results
$link =&gt; $mysqli_link
$length =&gt; $record_limit


These immediately give code reader exact understanding of what is stored in the variable.


You are doing nothing to validate the input to your function.  You shoudd consider validating, for example that a valid mysqli resource, non-zero length string for table name and where clause, and integer value for record limit are passed. Throw exception of fail out quickly if these conditions are not met.
Your code has no comments. You should always consider appropriate comments to make your code more readable.
Speaking of more readable code. You should strive to keep your code &lt; 80 chraracters per line.  You only have one questionable example in your code:


Here:


$ids_r = mysqli_query($link, 'select id from `' . $table . '`' .
($where ? ' where ' . $where : ''));



which could be made more readable like:

$where = $where ? ' WHERE ' . $where : '';
$sql = 'SELECT id FROM `' . $table . '`' . $where;
$id_results = mysqli_query($link, $sql);