FORCE INDEX mySQL ...where do I put it?

user2643870 picture user2643870 · Sep 28, 2013 · Viewed 104.2k times · Source

I have the following mySQL query that works perfectly fine. Except that I need to add a "FORCE INDEX" and I'm unsure on where I have to do this. I tried just about every location and always receive a mySQL error. What am I doing wrong?

Here is the original query:

$sql_select_recent_items = $db->query("SELECT * FROM (SELECT owner_id, product_id, start_time, price, currency, name, closed, active, approved, deleted, creation_in_progress FROM db_products ORDER BY start_time DESC) as resultstable
WHERE resultstable.closed=0 AND resultstable.active=1 AND resultstable.approved=1 AND resultstable.deleted=0 AND resultstable.creation_in_progress=0
GROUP BY resultstable.owner_id
ORDER BY start_time DESC");

The query is constructed this way so that I can do the "ORDER BY" before the "GROUP BY", in case you're wondering.

What I need to add is:

FORCE INDEX (products_start_time)

I tried it just about everywhere without success, which leads me to believe that there's something more complex that I'm missing?

Answer

Bill Karwin picture Bill Karwin · Sep 28, 2013

The syntax for index hints is documented here:
http://dev.mysql.com/doc/refman/5.6/en/index-hints.html

FORCE INDEX goes right after the table reference:

SELECT * FROM (
    SELECT owner_id,
           product_id,
           start_time,
           price,
           currency,
           name,
           closed,
           active,
           approved,
           deleted,
           creation_in_progress
    FROM db_products FORCE INDEX (products_start_time)
    ORDER BY start_time DESC
) as resultstable
WHERE resultstable.closed = 0
      AND resultstable.active = 1
      AND resultstable.approved = 1
      AND resultstable.deleted = 0
      AND resultstable.creation_in_progress = 0
GROUP BY resultstable.owner_id
ORDER BY start_time DESC

WARNING:

If you're using ORDER BY before GROUP BY to get the latest entry per owner_id, you're using a nonstandard and undocumented behavior of MySQL to do that.

There's no guarantee that it'll continue to work in future versions of MySQL, and the query is likely to be an error in any other RDBMS.

Search the tag for many explanations of better solutions for this type of query.