There is a table that contains such columns:
id, person_id, pet_id, description
There are some statements about this table:
- id is a primary key, autoincrement
- Each pair (person_id, pet_id) is unique
- id, person_id, pet_id is integer and is NOT NULL
- “holes” are possible (max pet_id doesn’t tell us there are totally (max) number of columns with such person_id)
- It is very possible there are much more different person_id in the table, that average number of pet_id for each person.
The question is: How to select random N pet_id of the current person_id fast?
Example of the table:
1. 1 1 cat
2. 1 2 dog
3. 2 40 horse
4. 2 35 dog
5. 3 46 duck
6. 2 39 duck
7. 1 3 duck
..................
100000 403 12 monkey
Example: I want to select two RANDOM rows for the person number two. One of possible random choices is the row #3. and the row #6.
The choices should be really “random” (should appear with the same probability).
How to do it using mysql query SELECT?
P.S. Of course I’ve read about selecting several random rows from the table, the basic problem with some tricky solutions. But, in my case there are two rows, not one.
I’m thinking of a faster method than
select id from tablename where person_id = 2 order by random() limit 2;
Your strawman query is as good as you can do. If you don’t have a person with lots of pets (and you have an index on
person_id), it should run quite fast. If you do have such a person, then you’re out of luck. Forget selecting randomly, even to determine how many pets such a person has requires time O(# pets).One possible other idea which probably won’t work for you: If you don’t care about the independence of your selections (i.e., you might get the same random response every time), then you can add a column which you populate with a random number when the row is inserted. Add an index on
person_id,random_columnand select the first N rows ordered by that pair. Slightly better is to add multiple random columns and select one to order by at random. Unfortunately, this doesn’t scale well and I don’t think you’d be happy with the results.