You've got enough money to pay for Oracle but not enough money for a test environment?
No answer (it's a bit long for a comment though) but some observations:
SSDs lie about their physical block size - this is actually the erase block size - which is huge.
Most disks also lie about their geometry (so you can format them from MS-DOS) - but this really hurts the performance of data striping RAID levels (but I wouldn't have expected too much impact on mirroring).
You've not shown us how they were partitioned nor what journalling you have configured.
You need to tell ext about RAID config - although again IIRC this is more of an issue for striping than mirroring.
Write operations on a mirror will never be faster (potentially up to 2x slower although more often its in the region of 20%) than to a single disk.
The problem with SSDs is write wear. In a mirror it's unusual for spinning rust disks, even from the same batch, to fail at the same time. OTOH its massivley more probable that 2 SSDs will fail at the same time. One solution is to deliberately stagger the lifespan of the disks. But if I were setting a machine with this hardware mix I'd have used mdadm to configure hybrid storage - mirror sets between SSD and HD.
I suspect that the problem is at the filesystem tier - if it were not in production, then I'd suggest giving Oracle access to the mirror device as a raw partition and checking the performance.
poige is exactly right about the write cache, but here are more details.
dd with zeros and using write cache is not the right way to benchmark (unless you want to test the write cache of course, which is probably only useful for a file system, to see how much it syncs metadata, creates new files, etc.) (and likely dd is always the wrong type of benchmark, but it works for a very basic test)
I suggest you use dd with at least one the following options:
conv=fdatasync -> this will make it flush to disk before finishing and calculating speed
oflag=direct -> this will make it skip the OS cache but not the disk cache
conv=sync -> more like skipping the disk cache too, but not really ... just flushing it every block or something like that.
And don't use zero either. Some smart hardware/software/firmware might use some shortcuts if the data is so predictable as zeros. This is especially true if there is compression which I am guessing you aren't using. Instead, use a random file in memory (such as /dev/shm). urandom is slow, so you need to write it somewhere temporarily to read it again.
Create a 50MB random file:
dd if=/dev/urandom of=/dev/shm/randfile bs=1M count=50
Read the file many times to write it (here I use cat to read it 6 times):
dd if=<(cat /dev/shm/randfile{,,,,,}) of= ... conv=fdatasync
rm /dev/shm/randfile
Also keep in mind that raid1 reads are fastest with parallel operations, so the disks can be used independently. It's probably not smart enough to coordinate the disks to read different parts of the same operation with different disks.
Best Answer
For that specific hardware combination, the controller cache may not provide much help.
The best performance enhancement you can make here is to leverage your LSI controller's FastPath functionality. This optimizes the data path for SSDs instead of the algorithms tuned for rotational media.