Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The <code>order_by('?')[:2]</code> solution suggested by other answers is actually an extraordinarily bad thing to do for tables that have large numbers of rows. It results in an <code>ORDER BY RAND()</code> SQL query. As an example, here's how mysql handles that (the situation is not much different for other databases). Imagine your table has one billion rows:</p> <ol> <li>To accomplish <code>ORDER BY RAND()</code>, it needs a <code>RAND()</code> column to sort on.</li> <li>To do that, it needs a new table (the existing table has no such column).</li> <li>To do that, mysql creates a new, temporary table with the new columns and copies the existing ONE BILLION ROWS OF DATA into it.</li> <li>As it does so, it does as you asked, and runs rand() for every row to fill in that value. Yes, you've instructed mysql to GENERATE ONE BILLION RANDOM NUMBERS. That takes a while. :)</li> <li>A few hours/days later, when it's done it now has to sort it. Yes, you've instructed mysql to SORT THIS ONE BILLION ROW, WORST-CASE-ORDERED TABLE (worst-case because the sort key is random).</li> <li>A few days/weeks later, when that's done, it faithfully grabs the two measly rows you actually needed and returns them for you. Nice job. ;)</li> </ol> <p>Note: just for a little extra gravy, be aware that mysql will initially try to create that temp table in RAM. When that's exhausted, it puts everything on hold to copy the whole thing to disk, so you get that extra knife-twist of an I/O bottleneck for nearly the entire process.</p> <p>Doubters should look at the generated query to confirm that it's <code>ORDER BY RAND()</code> then Google for "order by rand()" (with the quotes).</p> <p>A much better solution is to trade that one <em>really</em> expensive query for three cheap ones (limit/offset instead of <code>ORDER BY RAND()</code>):</p> <pre><code>import random last = MyModel.objects.count() - 1 index1 = random.randint(0, last) # Here's one simple way to keep even distribution for # index2 while still gauranteeing not to match index1. index2 = random.randint(0, last - 1) if index2 == index1: index2 = last MyObj1 = MyModel.objects.all()[index1] MyObj2 = MyModel.objects.all()[index2] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload