sqlite - SQLite 在 WHERE 子句中使用 OR 条件花费了太多时间
问题描述
我有一个包含1 亿行的 SQLite 数据库(表) 。
表架构:
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);
当我在不选择多个国家/地区的情况下使用以下这些简单查询时,我在15 毫秒内得到了响应。
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;
问题从以下查询开始
当我尝试使用OR条件查询匹配多个国家/地区时,需要60 秒才能响应。
SELECT * FROM users WHERE u_status = 1 AND (u_country = 'US' OR u_country = 'IN') ORDER BY u_score DESC LIMIT 10 OFFSET 100000;
查询改进1:
当我通过( INDEXED BY )强制查询使用特定索引时,它会在1 秒内响应
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;
查询改进2:
当我使用UNION ALL查询时,需要500 毫秒才能响应
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;
是否有可能在< 50 毫秒内获得响应,例如匹配多个国家/地区的第一次查询?
解决方案
在查询中使用OR
条件不允许使用索引。您可以将查询转换为UNION ALL
子句 -
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;
这可能会解决您的问题。
推荐阅读
- uwp-xaml - 如何在 UWP 的滚动查看器中启用水平滚动和禁用垂直滚动?
- javascript - React:使用扩展运算符使用表单数据 onChange 更新状态
- python - 为什么“组成”系列不会导致“输入”系列的索引?
- javascript - 在 webpack 设置中为 vuejs 保存一次性使用数据的位置
- c# - UWP 应用程序在发布时无法启动,“未找到依赖的 DLL”。在调试中工作,没有附加信息
- jquery - 为什么我需要嵌套的 jQuery document.ready 函数?
- three.js - 三个js启用阴影渲染慢
- r - 在 RI 中希望在文件夹中找到最新的 xlsx 文件,然后从该文件中导入数据
- wso2 - WSO2 流处理器:Siddhi App 计算总和
- powershell - 针对多个域的 PowerShell Active Directory 查询脚本的权限问题