To have PostgreSQL-like Partial Index in MySQL 5.5
Neither MySQL nor the siblings (MariaDB, Drizzle, etc) have implemented partial indexes.
What you can do, with this restriction in mind:
a) make a simple (not partial) index on
(is_active, measurement_id)
. It will be used in queries where the partial index would. Of course if theis_active
column is 3% True and 97% false, this index will be much bigger (than a partial index). But still smaller than the table and useful for these queries.
Another limitation is the index cannot beUNIQUE
with this solution so the constraint is not enforced. If the index is created withUNIQUE
, the uniqueness will be enforced for rows withis_active = FALSE
as well. I assume you don't want that:CREATE INDEX dir_events ON events (is_active, measurement_id) USING btree ;
b1) (the simple variation of b): add another table in your design, with only the primary key columns of
events
and a foreign key toevents
. This table should only have rows where theis_active
is true in the original table (this will be enforced by your application/procedures). Queries withis_active = TRUE
would be changed to join to that table (instead of theWHERE
condition.)
TheUNIQUE
is not enforced either with this solution but the queries would only do a simple join (to a much smaller index) and should be quite efficient:CREATE TABLE events_active ( event_id INT NOT NULL, -- assuming an INT primary key on events PRIMARY KEY (event_id), FOREIGN KEY (event_id) REFERENCES events (event_id) ) ; INSERT INTO events_active (event_id) SELECT event_id FROM events WHERE is_active = TRUE ;
b2) a more complex solution: add another table in your design, with only the primary key columns of the table and
measurement_id
. As in previous suggestion, this table should only have rows where theis_active
is true in the original table (this will be enforced by your application/procedures, too). Then use this table only instead for queries that haveWHERE is_active = TRUE
and need only themeasurement_id
column. If more columns are needed fromevents
, you'll have tojoin
, as before.
TheUNIQUE
constraint can be enforced with this solution. The duplication ofmeasurement_id
column can also be secured to be consistent (with an extra unique constraint onevents
and a composite foreign key):ALTER TABLE events ADD UNIQUE (event_id, measurement_id) ; CREATE TABLE events_active ( event_id INT NOT NULL, measurement_id INT NOT NULL. PRIMARY KEY (event_id, measurement_id), UNIQUE (measurement_id), FOREIGN KEY (event_id, measurement_id) REFERENCES events (event_id, measurement_id) ) ; INSERT INTO events_active (event_id, measurement_id) SELECT event_id, measurement_id FROM events WHERE is_active = TRUE ;
c) maybe the simplest of all: use PostgreSQL. I'm sure there are packages for your Linux distribution. They may not be the latest version of Postgres but partial indexes were added in 7.0 (or earlier?) so you shouldn't have a problem. Plus, I'm confident that you could install the latest version in almost any Linux distribution - even with a little hassle. You only need to install it once.