Assuming the two queries you mentionned will be "frequently" used, I would advise a composite index versus two distinct indexes on two columns.
As you already know, a query searching on two columns might sometimes use two separate indexes by (roughly) merging these two indexes into one. But this is sub-optimal, and has a cost in terms of performance.
Conversely, a composite index can only be used if the left-most columns are involved in the seach condition, or as the manual puts it:
MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on
With regards to your suggested hack (introducing dummy conditions so as to be able to use the index), this might work, but I would rather advise creating a second index on column2
only (besides the two-column index on (column1, column2)
). This comes at a (minor) cost, but is so much more elegant and reusable.
As for the suggestion of getting rid of NULL
values, I strongly disagree. It is sematnically incorrect to use 0
. 0
means "zero", NULL
means "no value". All your tests would need to account for this special value, whereas IS NULL
is standard and well understood everywhere. It is also just impractical in some situations (try to insert 0
with SQL_MODE='TRADITIONAL'
).
On the other hand, the performance gain is dubious (I believe this is mostly based on the false assumption that NULL
values are not indexed). It is easy to verify that a query like s.completed_time IS NOT NULL
will hit an index if such an index exists.