You should look at building more indexes. I think that in general, most people under-index their database.
This is still air-code, I haven't fully tested yet, but it should get you in the right direction
http://accessadp.com/2011/08/22/missing-indexes-great-script-for-determining-roi/
Select ‘create index IX_’ +
sys.objects.name +
isnull(replace(‘_’ + equality_columns, ‘,’, ‘_’), ”) +
isnull(replace(‘_’ + inequality_columns, ‘,’, ‘_’), ”) + ‘ on ‘ +
sys.objects.name +
‘(‘ +
coalesce(equality_columns + ‘,’ + inequality_columns, equality_columns , inequality_columns ) +
‘) ‘ +
isnull(‘ include (‘ + included_columns + ‘)’, ”)
as CreateIndexSql,
(CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.user_seeks)+CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.unique_compiles))*CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.avg_total_user_cost)*CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.avg_user_impact/100.0) AS Score,
sys.schemas.schema_id,
sys.schemas.name AS schema_name,
sys.objects.object_id,
sys.objects.name AS object_name,
sys.objects.type,
partitions.Rows, partitions.SizeMB,
sys.dm_db_missing_index_details.equality_columns,
sys.dm_db_missing_index_details.inequality_columns,
sys.dm_db_missing_index_details.included_columns,
sys.dm_db_missing_index_group_stats.unique_compiles,
sys.dm_db_missing_index_group_stats.user_seeks, sys.dm_db_missing_index_group_stats.user_scans,
sys.dm_db_missing_index_group_stats.avg_total_user_cost, sys.dm_db_missing_index_group_stats.avg_user_impact,
sys.dm_db_missing_index_group_stats.last_user_seek, sys.dm_db_missing_index_group_stats.last_user_scan,
sys.dm_db_missing_index_group_stats.system_seeks, sys.dm_db_missing_index_group_stats.system_scans,
sys.dm_db_missing_index_group_stats.avg_total_system_cost, sys.dm_db_missing_index_group_stats.avg_system_impact,
sys.dm_db_missing_index_group_stats.last_system_seek, sys.dm_db_missing_index_group_stats.last_system_scan
FROM
sys.objects
JOIN (
SELECT
object_id, SUM(CASE WHEN index_id BETWEEN 0 AND 1 THEN row_count ELSE 0 END) AS Rows,
CONVERT(numeric(19,3), CONVERT(numeric(19,3), SUM(in_row_reserved_page_count+lob_reserved_page_count+row_overflow_reserved_page_count))/CONVERT(numeric(19,3), 128)) AS SizeMB
FROM sys.dm_db_partition_stats
WHERE sys.dm_db_partition_stats.index_id BETWEEN 0 AND 1 –0=Heap; 1=Clustered; only 1 per table
GROUP BY object_id
) AS partitions ON sys.objects.object_id=partitions.object_id
JOIN sys.schemas ON sys.objects.schema_id=sys.schemas.schema_id
JOIN sys.dm_db_missing_index_details ON sys.objects.object_id=sys.dm_db_missing_index_details.object_id
JOIN sys.dm_db_missing_index_groups ON sys.dm_db_missing_index_details.index_handle=sys.dm_db_missing_index_groups.index_handle
JOIN sys.dm_db_missing_index_group_stats ON sys.dm_db_missing_index_groups.index_group_handle=sys.dm_db_missing_index_group_stats.group_handle
WHERE
sys.dm_db_missing_index_details.database_id=DB_ID()
AND (CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.user_seeks)+CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.unique_compiles))*CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.avg_total_user_cost)*CONVERT(Numeric(19,6), sys.dm_db_missing_index_group_stats.avg_user_impact/100.0) > 100