How can I get this query to use it's index?
Conditions with OR are harder for the optimizer than conditions with AND only.

Two or more range conditions (&gt;, &gt;=, &lt;, &lt;=, BETWEEN, LIKE 'search%') are harder than conditions with equality only or with only one range.

Your query has both the above difficulties. Noticing that it is equivalent to this rewriting:

WHERE ( languageId = 3 AND 
        isActive   = 1 AND 
        contentVersionId &gt; 1207494
      )
   OR ( languageId = 3 AND 
        isActive   = 1 AND 
        modifiedDateTime &gt; '2013-05-05 23:00:00.0'
      )


your best option is to have an index that can be used for the first part (equalities and one of the 2 range conditions) and another index for the second part (equalities and the other range):

ALTER TABLE cmContentVersion 
  ADD INDEX active_lang_contentversion_IX
    (isActive, languageId, contentVersionId),
  ADD INDEX active_lang_modified_IX
    (isActive, languageId, modifiedDateTime) ;


The optimizer might then choose to use both indexes and combine them with an Index-Merge access algorithm (the Sort-Union variation).



You can "force" the index-merge to be used by rewriting the query with derived tables.

SELECT cv.contentVersionId,
       cv.stateId,
       cv.modifiedDateTime,
       cv.versionComment,
       cv.isCheckedOut,
       cv.isActive,
       cv.contentId,
       cv.languageId,
       cv.versionModifier 
FROM   cmContentVersion AS cv
  JOIN
    (   SELECT contentVersionId
        FROM cmContentVersion 
        WHERE languageId = 3 AND 
              isActive   = 1 AND 
              contentVersionId &gt; 1207494
      UNION
        SELECT contentVersionId
        FROM cmContentVersion 
        WHERE languageId = 3 AND 
              isActive   = 1 AND 
              modifiedDateTime &gt; '2013-05-05 23:00:00.0'
    ) AS cvi   
      ON cvi.contentVersionId = cv.contentVersionId
ORDER BY cv.contentVersionId;




However, and since you have the ORDER BY, a combined index might be better for efficiency. Try adding this index:

(isActive, languageId, contentVersionId, modifiedDateTime)


and running the query as:

SELECT cv.contentVersionId,
       ...
FROM   cmContentVersion AS cv
WHERE ( languageId = 3 AND 
        isActive   = 1 AND 
        contentVersionId &lt;= 1207494 AND
        modifiedDateTime &gt; '2013-05-05 23:00:00.0'
      )
   OR ( languageId = 3 AND 
        isActive   = 1 AND 
        contentVersionId &gt; 1207494
      )
ORDER BY cv.contentVersionId;


and as:

SELECT cv.contentVersionId,
       ...
FROM   cmContentVersion AS cv
WHERE   languageId = 3 AND 
        isActive   = 1 AND 
        contentVersionId &lt;= 1207494 AND 
        modifiedDateTime &gt; '2013-05-05 23:00:00.0'
UNION ALL      
SELECT cv.contentVersionId,
       ...
FROM   cmContentVersion AS cv
WHERE   languageId = 3 AND 
        isActive   = 1 AND 
        contentVersionId &gt; 1207494
ORDER BY contentVersionId;