我正在使用Eclipselink,Spring Data和Postgresql。在我的项目中,我注意到当使用SpringData存储库提供的分页结果时,会出现类似以下查询:
SELECT COUNT(id)
FROM table
WHERE [part generated according to specification]
其中“ id”是“表”的主键。挖掘解释我注意到,对于一个非常大的表,COUNT(id)比COUNT()慢约10倍(count(id)在“ id”列中查找非空值,而count()仅返回匹配的行数)条件),count(*)也可以使用索引,而count(id)-不能。
我跟踪了SpringData基本存储库类,似乎只有JPA实现负责此查询的生成。
任何帮助表示赞赏
- [编辑] -
这里有张桌子:
\d ord_order
Table "public.ord_order"
Column | Type | Modificators
-------------------------+--------------------------+----------------------------------------------------------
id | integer | NOT NULL DEFAULT nextval('ord_order_id_seq'::regclass)
test_order | boolean | DEFAULT false
...
Indexes:
"pk_order" PRIMARY KEY, btree (id)
"idx_test_order" btree (test_order)
# explain SELECT COUNT(*) FROM ord_order WHERE (test_order = false);
QUERY PLAN
--------------------------------------------------------------------------
Aggregate (cost=89898.79..89898.80 rows=1 width=0)
-> Index Only Scan using idx_test_order on ord_order (cost=0.43..85375.37 rows=1809366 width=0)
Index Cond: (test_order = false)
Filter: (NOT test_order)
(4 wiersze)
# explain SELECT COUNT(id) FROM ord_order WHERE (test_order = false);
QUERY PLAN
--------------------------------------------------------------------------
Aggregate (cost=712924.52..712924.53 rows=1 width=4)
-> Seq Scan on ord_order (cost=0.00..708401.10 rows=1809366 width=4)
Filter: (NOT test_order)
(3 wiersze)
现在的区别是〜90k与〜713k以及索引扫描与全扫描
我设法提供了定制的Spring Data Repository基类实现以及使用该实现的工厂。结果生成的计数查询现在具有以下形式:
SELECT COUNT(1) FROM table
与COUNT(*)具有相同的计划。这似乎是很好的解决方案,并且可以在应用程序中对所有定义的存储库全局使用。
我不知道如何生成COUNT(*),COUNT(1)容易得多,因为COUNT函数期望某些表达式作为参数,并且我可以提供静态值-1
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句