【发布时间】:2023-04-08 02:54:01
【问题描述】:
我有一个数据库,其中有一个名为“links”的表,在 SQLite 中有 6 亿行。数据库中有 2 列 - “src”列和“dest”列。目前没有索引。
在 src 和 dest 之间有相当数量的公共值,但也有相当数量的重复行。
我要做的第一件事是删除所有重复的行,然后对结果进行一些额外的处理,但是我遇到了一些奇怪的问题。
首先,SELECT * FROM links WHERE src=434923 AND dest=5010182。现在这会很快返回一个结果,然后需要很长时间才能运行,因为我假设它正在对其余 600m 行执行表扫描。
但是,如果我执行SELECT DISTINCT * FROM links,那么它会立即开始快速返回行。问题是:这怎么可能?当然,对于每一行,该行都必须与表中的所有其他行进行比较,但这需要对表中剩余的行进行表扫描,这应该需要很长时间!
知道为什么SELECT DISTINCT 比标准的SELECT 快得多吗?
【问题讨论】:
-
你的数据库中有主键吗?
-
表的架构是什么? (请随意匿名。)
-
如果您反复读取 SQLite 文件,它将最终进入操作系统页面缓存。因此,重复读取可能会影响 RAM 而不是磁盘。取决于您的 RAM 与 DB 的大小以及盒子上发生的其他情况。
-
@Spike 6 亿行适合页面缓存?即使这是可能的,这如何解释一次扫描比另一次扫描更快?他们都会从记忆中阅读
-
想象一下两个查询同时实时运行。两者都在进行全表扫描。两者都读取第 1 行、第 2 行、第 3 行和第 4 行,确定它们是否与您的查询匹配并应发送给您。对于第一个查询,大多数行不匹配,因此您看不到任何输出并等待。对于第二个,大多数行都匹配,因此您会看到它们滚动。同样的速度,第二个感觉更快。
标签: sql database optimization sqlite