有许多选项具有不同的性能优势和权衡。
但所有工作都通过维护type by id 列的每个值的计数的第二个汇总表来工作。 (基本上,您将要提高性能的查询输出存储在数据库的表中,这是供以后使用简单快速的查询使用)
因此,由于您没有确切说明如何创建您正在使用的表,因此我不得不从您的查询中推断出示例
所以对于Data 表的创建者
CREATE TABLE "Data" (
"id" INTEGER NOT NULL,
"type" TEXT
)
您将创建第二个表来存储计数
CREATE TABLE "Data_summary" (
"type" TEXT NOT NULL,
"data_id" INTEGER NOT NULL,
"total_count" INTEGER,
UNIQUE ("type", "data_id")
)
(当您按 id 分组时,它必须是唯一约束以及 type 的一部分)
您想要加速的查询将是
SELECT * FROM Data_summary WHERE data_id != 123123123123
ORDER BY total_count DESC LIMIT 10
都有存储空间成本与查询速度的权衡,加上维护汇总表需要额外的工作,下面将详细介绍各种策略。
type 和 id 列的内容有多少不同的值并不重要,这只会使 Data_summary 表更大以便存储
选项:
1) 按照@stephenmwyatt22-w 的建议,使用Trigger 更新汇总表
(但我在回答一个工作示例时给出了实际细节)。
所以你会创建一个类似的触发器:-
CREATE TRIGGER update_summary AFTER INSERT ON Data
BEGIN
INSERT INTO Data_summary (type, data_id, total_count)
-- If Insert is success this is a new value of type so count is 1
VALUES (NEW.type, NEW.id, 1)
-- If value of type/id combo exists then there will be a conflict (this requires sqlite version 3.24.0 or later)
ON CONFLICT(type, data_id)
DO UPDATE SET total_count=total_count+1
WHERE type == NEW.type AND data_id == NEW.id;
END;
所以每次插入Data 时,都会自动对Data_summary 表进行第二次插入/更新(如果在将total_count 设置为为 1 否则插入时有一个 CONFLICT,因为它被设置为 UNIQUE 组合,因此使用 UPSERT 进程插入 UPDATE total_count + 1
这种方法的一个缺点是,如果您已经拥有包含数据的Data 表,那么您将使用代码中的一些“更新”sql 语句“引导”Data_summary 表(类似于@987654344 @) 在TRIGGER 接管维护Data_summary 表之前统计现有数据。
更新:
Online Demo
2)
您可以进行“批量”更新,而不是使用触发器来更新Data_summary 表。为此,您还需要有一个自动递增的唯一索引列整数或类似 DATE+TIME 列的东西来维护一个指向 Data_summary 最后更新到的位置的指针(这个“最后更新到”的指针需要存储在第三张表之类的地方)
当您想要对 Data_summary 表进行“更新”时,您可以像原来一样运行查询,但要使用额外的 WHERE 子句将查询限制为仅在您拥有的 Data 表中的“新”行上尚未在 Data_summary 表中进行汇总。
这将使用类似的ON CONFLICT 来插入新的id 和type 组合,或者更新现有组合的数量(如果它们已经存在)。
批量更新可以作为后台任务完成,也可以在需要结果之前完成,因为昂贵的查询只会针对“新”数据加上简单查询。
我不会给出一个例子,因为所有的 SQL 都与选项 1) 的例子非常相似。