搜索表格中具有与所提供列表中的任何列的组合匹配的行。

huangapple go评论81阅读模式
英文:

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:

  1. 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;

  2. Added index to the table:

    CREATE INDEX COFFEE_CONSUMPTION_IDX
    ON COFFEE_CONSUMPTION (C_CONCAT('', EMPLOYEE_ID, C_TO_CHAR(DDAY), TYPE));

  3. 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:

  1. 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;
    
  2. Added index to the table:

     CREATE INDEX COFFEE_CONSUMPTION_IDX 
         ON COFFEE_CONSUMPTION (C_CONCAT('', EMPLOYEE_ID, C_TO_CHAR(DDAY), TYPE));
    
  3. 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 = ? 

huangapple
  • 本文由 发表于 2023年2月19日 03:33:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75495899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定