Skip to content
Advertisement

Replace “OR” on 2 indexes with a faster solution (UNION?)

I’m querying shopping-carts in a shop-system, like:

I need to query records of c with a column which shows the number of carts which have the same user OR the same email. So I do:

This works, but the problem is that the OR is very slow, because MySQL/MariaDB doesn’t use any key in the subquery:

Even forcing the index doesn’t make the DB using it:

Using either column “email” or column “user” works fine, the key is used:

The problem is that the query runs on large table with about 500.000 entries, making the query taking about 30 seconds only to query a subset of 50 records. Running the query only with the match for “email” or only with the match for “user” it just takes about 1 second for 50 records.

So I need to optimize the query. I tried to change the OR into an UNION:

but I’m getting the error: ERROR 1054 (42S22): Unknown column ‘c.email’ in ‘where clause’

Any idea how to make this query using indexes to be faster?

Advertisement

Answer

This is an alternative approach using two left joins:

This can use separate indexes on c(user) and c(email).

Basically, this joins along the two separate dimensions, and then brings them together for the count(distinct). There are some worse case scenarios where there might be lots of matches along both dimensions. However, in many cases this might prove to work quite well because it can use the indexes rather than scanning the entire table for each row.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement