Reputation: 15548
I have a SQLite database (table) with 100 million rows.
Table schema:
CREATE TABLE users
(
u_id VARCHAR(32) PRIMARY KEY,
u_status BOOLEAN,
u_country VARCHAR(2),
u_score INT
);
CREATE INDEX dex_sta ON users (u_status);
CREATE INDEX dex_cou ON users (u_country);
CREATE INDEX dex_sco ON users (u_score);
CREATE INDEX dex_sns ON users (u_status, u_score);
CREATE INDEX dex_mul ON users (u_status, u_country, u_score);
When I use these below simple queries without choosing multiple countries I got response in 15 ms.
SELECT * FROM users WHERE u_status = 1 AND u_country = 'US' ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
SELECT * FROM users WHERE u_status = 1 AND u_country = 'IN' ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
When I try to match multiple countries with OR condition query takes 60 seconds to respond.
SELECT * FROM users WHERE u_status = 1 AND (u_country = 'US' OR u_country = 'IN') ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
When I force query to use specific INDEX via (INDEXED BY) it responded in 1 second
SELECT * FROM users INDEXED BY dex_mul WHERE u_status = 1 AND (u_country = 'US' OR u_country = 'IN') ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
When I'm using UNION ALL query it takes 500 milliseconds to respond
SELECT * FROM users WHERE u_status = 1 AND u_country = 'US'
UNION ALL
SELECT * FROM users WHERE u_status = 1 AND u_country = 'IN'
ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
Is it possible to get response in < 50 ms like first query with matching multiple countries?
Upvotes: 1
Views: 184
Reputation: 13509
Using the OR
condition in the query doesn't allow the use of Indexes. You can convert your query to UNION ALL
clause -
SELECT *
FROM users
WHERE u_status = 1 AND u_country = 'US'
UNION ALL
SELECT *
FROM users
WHERE u_status = 1 AND u_country = 'IN'
ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
This might solve your problem.
Upvotes: 1