英文:
Search table for rows with combination of N columns matching any from the provided list
问题
以下是您要翻译的内容:
"I have a COFFEE_CONSUMPTION
table with 5 columns in Postgres. It can grow up to e.g. 1 million rows and more.
We need to search for records with EMPLOYEE_ID+DAY+TYPE
combination matching one of those from the provided list.
Looking for an index-wise implementation I came up with such a solution:
-
Created 2 immutable functions
CREATE OR REPLACE FUNCTION C_CONCAT(text, VARIADIC text[])
RETURNS text
LANGUAGE sql
IMMUTABLE PARALLEL SAFE AS
'SELECT array_to_string($2, $1)';CREATE FUNCTION C_TO_CHAR(date) RETURNS text AS
$$
select to_char($1, 'YYYY-MM-DD');
$$
LANGUAGE sql immutable; -
Added index to the table:
CREATE INDEX COFFEE_CONSUMPTION_IDX
ON COFFEE_CONSUMPTION (C_CONCAT('', EMPLOYEE_ID, C_TO_CHAR(DDAY), TYPE)); -
Wrote a query:
SELECT *
FROM COFFEE_CONSUMPTION CC
WHERE C_CONCAT('', CC.EMPLOYEE_ID, C_TO_CHAR(CC.DDAY), CC.TYPE) IN ?
Any ideas on how to improve this and/or get rid of custom functions?
One of possible approaches would be to create a multi-column index, populate a temporary table with field combinations and inner join in select (as described here). But I believe this would be more verbose, more complex from client programming (e.g. JPA) perspective and equally performant.
UPD: the main problem turned out to be not the SQL query but JPA+Hibernate stack which doesn't allow querying by list of lists. So I decided to stick to the functions solution for now."
英文:
I have a COFFEE_CONSUMPTION
table with 5 columns in Postgres. It can grow up to e.g. 1 million rows and more.
EMPLOYEE_ID|ROOM_ID|DDAY |COUNT|TYPE |
-----------------------------------------------------
1 |1 |2023-02-16|1 |latte |
1 |1 |2023-02-16|3 |espresso |
2 |1 |2023-02-16|2 |latte |
3 |2 |2023-02-16|1 |espresso |
4 |2 |2023-02-17|3 |frappuccino |
... |... |... |... |... |
We need to search for records with EMPLOYEE_ID+DAY+TYPE
combination matching one of those from the provided list.
Looking for an index-wise implementation I came up with such a solution:
-
Created 2 immutable functions
CREATE OR REPLACE FUNCTION C_CONCAT(text, VARIADIC text[]) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE AS 'SELECT array_to_string($2, $1)'; CREATE FUNCTION C_TO_CHAR(date) RETURNS text AS $$ select to_char($1, 'YYYY-MM-DD'); $$ LANGUAGE sql immutable;
-
Added index to the table:
CREATE INDEX COFFEE_CONSUMPTION_IDX ON COFFEE_CONSUMPTION (C_CONCAT('', EMPLOYEE_ID, C_TO_CHAR(DDAY), TYPE));
-
Wrote a query:
SELECT * FROM COFFEE_CONSUMPTION CC WHERE C_CONCAT('', CC.EMPLOYEE_ID, C_TO_CHAR(CC.DDAY), CC.TYPE) IN ?
Any ideas on how to improve this and/or get rid of custom functions?
One of possible approaches would be to create a multi-column index, populate a temporary table with field combinations and inner join in select (as described here). But I believe this would be more verbose, more complex from client programming (e.g. JPA) perspective and equally performant.
UPD: the main problem turned out to be not the SQL query but JPA+Hibernate stack which doesn't allow querying by list of lists. So I decided to stick to the functions solution for now.
答案1
得分: 1
我不明白为什么您需要自定义函数的复杂性:
在 coffee_consumption 上创建索引 (employee_id, dday, type);
如果您运行以下查询,该索引应该会被使用:
select *
from coffee_consumption cc
where (cc.employee_id, cc.dday, cc.type) in (?,?,?)
或者
select *
from coffee_consumption cc
where cc.employee_id = ?
cc.dday = ?
cc.type = ?
英文:
I don't see why you need that complication with a custom function:
create index on coffee_consumption (employee_id, dday, type);
That index should be used if you run:
select *
from coffee_consumption cc
where (cc.employee_id, cc.dday, cc.type) in (?,?,?)
or
select *
from coffee_consumption cc
where cc.employee_id = ?
cc.dday = ?
cc.type = ?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论