对于大型数据集,哪个选项更好,选择vs case
案例:
SELECT SUM(CASE WHEN(created_at > (CURRENT_DATE - INTERVAL '1 days')) THEN 1 ELSE 0 END) as day_count,
SUM(CASE WHEN(created_at > (CURRENT_DATE - INTERVAL '1 months')) THEN 1 ELSE 0 END) as month_count,
SUM(CASE WHEN(created_at > (CURRENT_DATE - INTERVAL '3 months')) THEN 1 ELSE 0 END) as quater_count,
SUM(CASE WHEN(created_at > (CURRENT_DATE - INTERVAL '6 months')) THEN 1 ELSE 0 END) as half_year_count,
SUM(CASE WHEN(created_at > (CURRENT_DATE - INTERVAL '1 years')) THEN 1 ELSE 0 END) as year_count,
count(*) as total_count from wallets;
多项选择查询:
SELECT count(*) from wallets where created_at > CURRENT_DATE - INTERVAL '1 days';
SELECT count(*) from wallets where created_at > CURRENT_DATE - INTERVAL '1 months';
SELECT count(*) from wallets where created_at > CURRENT_DATE - INTERVAL '3 months';
SELECT count(*) from wallets where created_at > CURRENT_DATE - INTERVAL '6 months';
SELECT count(*) from wallets where created_at > CURRENT_DATE - INTERVAL '1 years';
SELECT count(*) from wallets;
要求是按日,月,3个月,6个月和每年查找钱包数。 如果我选择多个选择,那么将需要6个查询来获取数据。
使用switch case我们可以在一个查询中获取数据,但我不确定最佳做法是将switch case用于大型数据集。
请查看下面的查询分析,我的数据库中只有10条记录:
案例查询分析:
多个查询分析:
答案 0 :(得分:2)
单个查询会更好。使用filter
:
SELECT COUNT(*) FILTER (WHERE created_at > (CURRENT_DATE - INTERVAL '1 days')) as day_count,
COUNT(*) FILTER (WHERE created_at > (CURRENT_DATE - INTERVAL '1 months')) as month_count,
COUNT(*) FILTER (WHERE created_at > (CURRENT_DATE - INTERVAL '3 months')) as quater_count,
COUNT(*) FILTER (WHERE created_at > (CURRENT_DATE - INTERVAL '6 months')) as half_year_count,
COUNT(*) FILTER (WHERE created_at > (CURRENT_DATE - INTERVAL '1 years')) as year_count,
COUNT(*) as total_count
FROM wallets;
如果你有created_at
的索引,那么这也应该有助于Postgres优化只使用该索引。
答案 1 :(得分:0)
从knex的角度来看,区别在于可以通过单独的连接向DB发送多个查询并并行执行。执行单个查询可能会在整体上提高性能,从而减少数据库服务器上的压力/数据传输开销。
执行查询的第一种方法的最大缺点是你无法使用knex很好地构建它,并且对于读取代码的人来说它看起来很糟糕。
实现这种将多个查询打包为单一的更好方法是使用postgres with
语句(公用表表达式)https://www.postgresql.org/docs/9.6/static/queries-with.html,其中knexalso支持http://knexjs.org/#Builder-with
编辑:或者只是在单一选择中进行多次查询,有点像Gordon Linoff建议:
knex
.select(
knex('wallets')
.where('createad_at', '>', knex.raw("CURRENT_DATE - INTERVAL '1 days'"))
.count()
.as('lastDay'),
knex('wallets')
.where('createad_at', '>', knex.raw("CURRENT_DATE - INTERVAL '1 months'"))
.count()
.as('lastMonth'),
... rest of the queries ...
);
https://runkit.com/embed/wsy01ar1hb73
postgresql应该能够使用Gordon的回答促进的类似计划来优化多个子查询。
答案 2 :(得分:0)
我可以做一个有根据的猜测。没有实际的数据测试几乎没用。
多选查询更容易通过数据库平面进行优化。 PostgreSQL 9.6+可以使用index only scans。它可能会以一些非常快速的查询结束。
案例非常难以阅读。我担心没有人可以为此编写索引,查询将被强制扫描整个表。这可能是一个非常缓慢的操作。