The VRAM is not a disk, it's a Random Access Memory. OpenGL doesn't need to scan it through to reach something on it. There's usually a memory table stored somewhere, which keeps track of the locations of the buffers and vertex arrays. There's also a pointer that points to the current VAO, VBO, IBO, texture, framebuffer, etc.
When you use one of the glBindXYZ
functions, you pass a handle to OpenGL. It then looks up the pointer to the bufffer/vertex array/texture/etc from the memory table, and sets the relevant pointer to the result.
The gen functions work like this, because most people know how many vbos or vaos they'll need, and this makes creating them easier. It's only a problem, when you have a variable amount of vbos.
Creating multiple buffers at once doesn't have an advantage over creating them one-by-one right after each other in terms of memory layout. Both
glCreateBuffers(1, &handle1);
// Stuff
glCreateBuffers(1, &handle2);
// Stuff
glCreateBuffers(1, &handle3);
// Stuff
and
glCreateBuffers(3, &handles);
// Stuff x 3
result in the same. In both cases the vbos are as close as possible (if they are already used up memory blocks where the next vbo should go, then it will be a bit further away from the others.