One more for good measure from the prolific Frederic Nevers:
He's on a roll.
From the article:
Q: If I add a lot of images on my course pages, will it affect performance?
A: Yes, it will. The number of reads/writes to the database skyrockets when you add images in labels. A page with 100 images requires over 3 times the amount of calls to the database compared with a page with no images in labels. Looking at iMacros loading pages during the tests, I also noticed that images inserted as URL’s (i.e. not uploaded to Moodle) show up much faster in Moodle pages than the images uploaded to Moodle.
That's really interesting. Seems that 2.x moodle's approach to dumping images into the database as blobs is really hard on servers compared to 1.9.x's simply storing them in the moodledata directory.
Again the big problem i think for most people is how much CPU/SQL is used per call. It limits how many students can put in requests AT THE EXACT same time. Moodle can handle a million students as long as they don't all push a button or login within 2 seconds of each other.
I really wish that Moodle had a queueing architecture where requests could be queued rather than requsting everything processing
Where are you seeing that Moodle stores binary data (e.g. images) as blobs? I haven't seen that in practice.
What is the possible bottleneck is that every image on Moodle is served by the /pluginfile.php. It does a lot of processing to find out what part of Moodle is serving the file, calls that part's lib.php's "*_pluginfile" function to do access control.
This happens for every module icons and editing icons as well. A nice performance optimization might be to use CSS sprites (http://friendlybit.com/css/spriteme-combine-images-and-get-fewer-http-requests/) to reduce HTTP calls. However, I believe that Moodle tries to set the appropiate cache headers so that a browser should only really request an icon once during a session.
Rex is correct - Moodle does not store any binary data in the database, what it does do though is to hash (SHA1) the content of the file. The file is then stored in an appropriate location on disk (in moodledata) based on this hash.
This is actually pretty good for performance as it theoretically reduces the number of files per directory as data is sharded over the entire filesystem - many file systems can get pretty slow to complete a stat of a directory when large numbers of files are in that directory.
I don't believe that there are that many more SQL queries for an image in a label. There will be more of course than for a label without any image, but that was also the case in Moodle 1.9. Every file fetched from Moodle has permissions checked as appropriate. This will include a range of checks from requiring login, to checking whether the section that the file is in is actually visible, and whether that user has access to it.
As Rex suggests, pluginfile.php tries to include as many cacheable headers as possible but many requests to display a file in Moodle does still necessite the permissions checks even if the actual file content is not delivered every time.
One thing which we've found massively helps our performance is to use X-Accel-Redirect to inform the web server of the file's location and get the webserver to serve the actual content (web servers are really good at this). For us this improved performance noticably. I did post in the Hardware and Perfomance forum recently about this.