我知道不同的含义,也生成系列。但是当我执行这个查询时,问号在我脑海中飞舞。
select distinct generate_series(0,8)
结果非常奇怪。
有人可以帮我解释发生了什么吗?
我知道不同的含义,也生成系列。但是当我执行这个查询时,问号在我脑海中飞舞。
select distinct generate_series(0,8)
结果非常奇怪。
有人可以帮我解释发生了什么吗?
没有子句的SELECT
查询没有定义 order,它只会以方便执行 DBMS 的任何顺序返回相关行。ORDER BY
在“真实”表的情况下,这可能是 PRIMARY KEY 的顺序,它们被插入到表中的顺序,或者是执行计划中使用的特定索引的顺序。
在这个例子中,创建的“表”generated_series()
显然是按 0、1、2、3 等顺序开始DISTINCT
的。但是,为了检查您对查询施加的约束,Postgres 必须做一些事情来检查项目是否出现不止一次。(它无法知道该generate_series()
函数将始终提供不同的值。)
执行此操作的一种有效方法(通常)是构建要检查唯一性的值的“散列图”。您无需根据每个现有值检查每个新值,而是计算它将落入哪个“哈希桶”;如果桶为空,则值是唯一的;如果没有,您只需将其与该存储桶中的其他值进行比较。
运行EXPLAIN select distinct generate_series(0,8)
会显示 Postgres 选择的查询计划;对我(大概对你)来说,这看起来像这样:
HashAggregate (cost=0.02..0.03 rows=1 width=0)
-> Result (cost=0.00..0.01 rows=1 width=0)
正如预期的那样,那里有一个HashAggregate
操作,运行结果generate_series()
以检查它的唯一性。(该操作的具体工作原理我不知道,也不重要,但名字强烈暗示它使用哈希映射来完成工作)。
在散列操作结束时,Postgres 可以简单地从散列映射中读出值,而不是返回到原始列表,所以它这样做了。结果,它们不再是原来的顺序,而是按照它们落入的“哈希桶”进行排序。
这个故事的寓意是:总是使用ORDER BY
从句!