PAGEIOLATCH_SH and LCK_M_IX wait type
There are a few causes of this, the top ones are: storage subsystem, bad t-sql, missing/bad indexes.  Paul Randall talks about this on his blog and at the sqlperformance blog.  I like the scripts from Glenn Berry to find missing indexes and also SP_BlitzIndex.  

How do you know if you can trust the recommendations?  Well I examine the existing indexes first to see what I have and if they can be altered to accommodate the missing columns.  I also like to look in the plan cache to get an idea of what some of the top queries are on that table to see if it would actually make a difference.  If you have a test/dev instance, you can implement there first which will give you an idea of the size any possibly usage pattern if you can generate a workload.  If you are going right into prod, monitor sys.dm_db_index_usage_stats (check the index reads/writes query in Glenn Berry's DMV queries)and check the reads/writes to ensure it is used.  You could also use SQL Sentry's Plan Explorer, but I think you need the pro version for the indexes.  

I'm sure someone has a better way to do it, but this has been working for me so far.