Of course, you can use the RAND() function to query using LIMIT and WHERE (for a category). This, as you indicated, entails a database scan that takes time, especially in your case due to the amount of data.
Your other alternative, again, as you indicated, for storing id / category_id in another table may be a little faster, but again there should be LIMIT and WHERE in this table, which will also contain the same amount of records as the main table.
Another approach (if applicable) should be to have a table for each category and store identifiers in it. If your categories are fixed or often do not change, you should be able to use this approach. In this case, you will effectively remove WHERE from the sentence, and getting RAND() with LIMIT in each category table will be faster, since each category table will contain a subset of the entries from your main table.
Some other alternatives are to use a key / value pair database for this operation only. MongoDb or Google AppEngine can help with this and really fast.
You can also move on to the master / slave approach in your MySQL. The slave replicates the content in real time, but when you need to complete an expensive request, you request the slave instead of the master, transferring the load to another machine.
Finally, you can go with Sphinx, which is much easier to install and maintain. You can then process each of these queries into categories as a document search and let Sphinx randomize the results. Thus, you take this expensive operation to another level and allow MySQL to continue other operations.
Just some issues to consider.
source share