EntityFramework6 / Npgsql:如何将 orderBy nulls last 转换为 SQL 查询
EntityFramework6 / Npgsql: how to translate orderBy nulls last into SQL query
我正在使用 EntityFramework6.Npgsql 并且正在处理包含几百万条记录的表。一些实体有一个 timestamp
/ DateTime
列,允许 null
值。用户通常需要对此列进行排序,并希望在 asc
和 desc
排序中最后显示 null
值。该列有两个索引用于两种排序类型,它们都设置为 nulls last
我知道在 SQL 中我可以添加 order by "DateColumn" desc nulls last
并且 postgres 使用适当的索引和查询 returns(分页,例如 25 条记录)在几毫秒内产生结果。
然而,对于 EntityFramework,为了最后对空值进行降序排序,我必须添加如下内容:
entities.MyEntity
.OrderByDescending(e => e.DateColumn.HasValue)
.ThenByDescending(e => e.DateColumn)
然而,这会转化为一个查询,其中包含用于排序的类似内容:
SELECT
CASE
WHEN ("Extent1"."DateColumn" IS NOT NULL) THEN (TRUE)
ELSE (FALSE)
END AS "C1"
...
ORDER BY "C1", "DateColumn" DESC
按预期工作,但查询需要几秒钟(而不是几毫秒)才能执行,因为它无法使用索引。
我尝试用相同的表达式向列添加索引,但 postgres 在执行查询时似乎没有使用索引。
在 EntityFramework / Npgsql 中编写可以转换为所需 SQL (order by "DateColumn" desc nulls last
) 的查询有哪些选项?有没有办法 intercept/overwrite Linq 查询是如何翻译成 SQL?
回答我自己的问题...
虽然仍然无法让 Linq 生成按 nulls last
排序的 SQL 查询,但我能够为 null-check 和日期列本身创建一个组合索引,即正在被 postgres 使用:
CREATE INDEX "MyTable_IX_DateCombined"
ON "MyTable"
USING btree
((
CASE
WHEN "DateColumn" IS NOT NULL THEN true
ELSE false
END) DESC, "DateColumn" DESC);
因为在任何一种情况下我都必须创建一个额外的索引,所以我认为这个解决方案在这一点上已经足够好了。
我正在使用 EntityFramework6.Npgsql 并且正在处理包含几百万条记录的表。一些实体有一个 timestamp
/ DateTime
列,允许 null
值。用户通常需要对此列进行排序,并希望在 asc
和 desc
排序中最后显示 null
值。该列有两个索引用于两种排序类型,它们都设置为 nulls last
我知道在 SQL 中我可以添加 order by "DateColumn" desc nulls last
并且 postgres 使用适当的索引和查询 returns(分页,例如 25 条记录)在几毫秒内产生结果。
然而,对于 EntityFramework,为了最后对空值进行降序排序,我必须添加如下内容:
entities.MyEntity
.OrderByDescending(e => e.DateColumn.HasValue)
.ThenByDescending(e => e.DateColumn)
然而,这会转化为一个查询,其中包含用于排序的类似内容:
SELECT
CASE
WHEN ("Extent1"."DateColumn" IS NOT NULL) THEN (TRUE)
ELSE (FALSE)
END AS "C1"
...
ORDER BY "C1", "DateColumn" DESC
按预期工作,但查询需要几秒钟(而不是几毫秒)才能执行,因为它无法使用索引。
我尝试用相同的表达式向列添加索引,但 postgres 在执行查询时似乎没有使用索引。
在 EntityFramework / Npgsql 中编写可以转换为所需 SQL (order by "DateColumn" desc nulls last
) 的查询有哪些选项?有没有办法 intercept/overwrite Linq 查询是如何翻译成 SQL?
回答我自己的问题...
虽然仍然无法让 Linq 生成按 nulls last
排序的 SQL 查询,但我能够为 null-check 和日期列本身创建一个组合索引,即正在被 postgres 使用:
CREATE INDEX "MyTable_IX_DateCombined"
ON "MyTable"
USING btree
((
CASE
WHEN "DateColumn" IS NOT NULL THEN true
ELSE false
END) DESC, "DateColumn" DESC);
因为在任何一种情况下我都必须创建一个额外的索引,所以我认为这个解决方案在这一点上已经足够好了。