SELECT가 중첩 된 INSERT를 사용하는 함수보다 "빠름"입니까?

상자

테이블에 행이없는 경우 행을 삽입 한 다음 행의 ID를 반환하는 함수를 사용하고 있습니다.

SELECT아직 테이블에 존재하지 않는 값 으로 명령문 안에 함수를 넣을 때마다 , 예 :

SELECT * FROM table WHERE id = function(123);

... 빈 행을 반환합니다. 그러나 동일한 값으로 다시 실행하면보고 싶은 값이있는 행이 반환됩니다.

왜 이런 일이 발생합니까? 는 IS INSERT뒤에서 실행 SELECT속도는? 아니면 PostgreSQL이 테이블이 존재하지 않았을 때 캐시하고 다음 실행시 결과를 표시합니까?

이 문제가 발생하는 방법에 대한 사용 가능한 예는 다음과 같습니다.

CREATE TABLE IF NOT EXISTS test_table(
id INTEGER,
tvalue boolean
);

CREATE OR REPLACE FUNCTION test_function(user_id INTEGER)
    RETURNS integer
    LANGUAGE 'plpgsql'
AS $$
DECLARE
    __user_id INTEGER;

BEGIN
    EXECUTE format('SELECT * FROM test_table WHERE id = $1')
    USING user_id
    INTO __user_id;

    IF __user_id IS NOT NULL THEN
        RETURN __user_id;

    ELSE
        INSERT INTO test_table(id, tvalue)
        VALUES (user_id, TRUE) 
        RETURNING id
        INTO __user_id;
        RETURN __user_id;
    END IF;
END;
$$;

요구:

SELECT * FROM test_table WHERE id = test_function(4);

문제를 재현하려면 아직 테이블에없는 정수를 전달하십시오.

Erwin Brandstetter

예제는 여러 곳에서 나뉩니다.

  • .NET과 함께 동적 SQL이 필요하지 않습니다 EXECUTE.
  • SELECT * 기능이 잘못되었습니다.
  • 테이블 정의에는에 대한 UNIQUE또는 PRIMARY KEY제약 조건 이 있어야합니다 (id).
  • 가장 중요한 것은 최종 SELECT진술이 실패 할 수밖에 없다는 것입니다. 때문에 함수이다VOLATILE (수 있음), 이것은 한 번씩 평가 테이블의 기존 행. 그게 효과가 있더라도 성능 악몽이 될 것입니다. 그러나 그렇지 않습니다. @ user2864740이 댓글을 단 것처럼 가시성 에도 문제 있습니다 . Postgres는 함수의 결과에 대해 기존의 모든 행을 확인 합니다. 그러면 1 개 이상의 행이 추가되고 해당 행은 아직 SELECT작동중인 스냅 샷에 없습니다 .

    SELECT * FROM test_table WHERE id = test_function(4);

이것은 작동 할 것입니다 (그러나 아래 참조!) :

CREATE TABLE test_table (
  id     int PRIMARY KEY  --!
, tvalue bool
);

CREATE OR REPLACE FUNCTION test_function(_user_id int)
  RETURNS test_table LANGUAGE sql AS
$func$
   WITH ins AS (
      INSERT INTO test_table(id, tvalue)
      VALUES (_user_id, TRUE) 
      ON CONFLICT DO NOTHING
      RETURNING *
      )
   TABLE ins
   UNION ALL
   SELECT * FROM test_table WHERE id = _user_id
   LIMIT 1
$func$;

그리고 다음으로 교체하십시오 SELECT.

SELECT * FROM test_function(1);

db <> 여기에 바이올린

관련 :

동시 호출 에는 여전히 경쟁 조건 이 있습니다 . 그럴 수 있다면 다음을 고려하십시오.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Python3 : 더 빠른 것, 중첩 된 함수 호출 또는 if 문 (시도 / 예외가 매우 빠름)

분류에서Dev

함수를 사용하면 하위 쿼리가 더 빠름

분류에서Dev

내 보낸 함수에 중첩 된 개체를 분해하고 추가하는 방법은 무엇입니까?

분류에서Dev

중첩 된 for-loop 및 String replace 함수를 사용하는 데 문제가 있습니다

분류에서Dev

중첩 된 switch 문 중에 사용자가 문자를 입력하도록 허용 할 수 있습니까?

분류에서Dev

함수 객체에 중첩 된 함수를 호출하는 것이 ...보다 고정 된 이유는 무엇입니까?

분류에서Dev

중첩 된 뷰와 함께 ui-router를 사용할 때 사용자 컨트롤러를 추가하는 방법은 무엇입니까?

분류에서Dev

재귀를 사용하여 중첩 된 for 루프의 가변 수를 처리하는 방법은 무엇입니까?

분류에서Dev

전체 경로를 가져 오지 않고 중첩 된 모듈의 함수를 사용할 수있는 이유는 무엇입니까?

분류에서Dev

스키마에서 중첩 된 람다를 사용하는 이유는 무엇입니까?

분류에서Dev

중첩 된 메뉴 항목에 사용자 정의 키보드 단축키를 추가하는 방법은 무엇입니까?

분류에서Dev

중첩 데이터에 대해 vuetify 2와 함께 vuelidate를 사용하는 방법은 무엇입니까? 잘못된 필드 가져 오기

분류에서Dev

jquery를 사용하여 중첩 된 JSON 개체에서 값을 가져 오는 방법은 무엇입니까?

분류에서Dev

Angular 구성 요소와 함께 중첩 된 Flexbox를 사용하는 방법은 무엇입니까?

분류에서Dev

getStaticPaths와 함께 여러 중첩 된 동적 경로를 사용하는 방법은 무엇입니까?

분류에서Dev

중첩 된 div에서 다른 CSS 불투명도를 사용하는 방법은 무엇입니까?

분류에서Dev

중첩 SELECT를 사용하여 INSERT 쿼리에 대해 삽입 된 행 수를 어떻게 얻습니까? affect_rows, result_id, num_rows에 운이 없습니다.

분류에서Dev

중첩 된 함수가 작동하지 않습니다.

분류에서Dev

rsync가 중첩 된 디렉토리를 포함하지 않는 이유는 무엇입니까?

분류에서Dev

중첩 된 클래스가 포함하는 클래스 중 하나 인 유형의 멤버를 가질 수없는 이유는 무엇입니까?

분류에서Dev

함수를 사용하여 동적 배열 크기를 늘리십시오. 무료 오류, 잘못된 다음 크기 (빠름)

분류에서Dev

중첩 된 forEach 및 for 루프가있는 함수는 false를 반환하지 않습니다.

분류에서Dev

Mongoose의 다른 배열에 중첩 된 배열에 요소를 추가하는 방법은 무엇입니까?

분류에서Dev

gcc는 중첩 된 일반 람다를 사용하여이 코드를 수락하고 clang이 거부합니다. 이유는 무엇입니까?

분류에서Dev

람다 함수를 사용하여 중첩 된 목록 교차

분류에서Dev

중첩 된 sort ()를 사용하여 중첩 된 배열을 정렬 할 수 있습니까?

분류에서Dev

jQuery는 함수 매개 변수를 중첩 된 함수로 전달합니다.

분류에서Dev

React에서 화살표 함수로 상수로 정의 된 중첩 된 구성 요소를 사용하는 방법은 무엇입니까?

분류에서Dev

중첩 된 HashMaps를 사용하는 것이 나쁜 습관입니까?

Related 관련 기사

  1. 1

    Python3 : 더 빠른 것, 중첩 된 함수 호출 또는 if 문 (시도 / 예외가 매우 빠름)

  2. 2

    함수를 사용하면 하위 쿼리가 더 빠름

  3. 3

    내 보낸 함수에 중첩 된 개체를 분해하고 추가하는 방법은 무엇입니까?

  4. 4

    중첩 된 for-loop 및 String replace 함수를 사용하는 데 문제가 있습니다

  5. 5

    중첩 된 switch 문 중에 사용자가 문자를 입력하도록 허용 할 수 있습니까?

  6. 6

    함수 객체에 중첩 된 함수를 호출하는 것이 ...보다 고정 된 이유는 무엇입니까?

  7. 7

    중첩 된 뷰와 함께 ui-router를 사용할 때 사용자 컨트롤러를 추가하는 방법은 무엇입니까?

  8. 8

    재귀를 사용하여 중첩 된 for 루프의 가변 수를 처리하는 방법은 무엇입니까?

  9. 9

    전체 경로를 가져 오지 않고 중첩 된 모듈의 함수를 사용할 수있는 이유는 무엇입니까?

  10. 10

    스키마에서 중첩 된 람다를 사용하는 이유는 무엇입니까?

  11. 11

    중첩 된 메뉴 항목에 사용자 정의 키보드 단축키를 추가하는 방법은 무엇입니까?

  12. 12

    중첩 데이터에 대해 vuetify 2와 함께 vuelidate를 사용하는 방법은 무엇입니까? 잘못된 필드 가져 오기

  13. 13

    jquery를 사용하여 중첩 된 JSON 개체에서 값을 가져 오는 방법은 무엇입니까?

  14. 14

    Angular 구성 요소와 함께 중첩 된 Flexbox를 사용하는 방법은 무엇입니까?

  15. 15

    getStaticPaths와 함께 여러 중첩 된 동적 경로를 사용하는 방법은 무엇입니까?

  16. 16

    중첩 된 div에서 다른 CSS 불투명도를 사용하는 방법은 무엇입니까?

  17. 17

    중첩 SELECT를 사용하여 INSERT 쿼리에 대해 삽입 된 행 수를 어떻게 얻습니까? affect_rows, result_id, num_rows에 운이 없습니다.

  18. 18

    중첩 된 함수가 작동하지 않습니다.

  19. 19

    rsync가 중첩 된 디렉토리를 포함하지 않는 이유는 무엇입니까?

  20. 20

    중첩 된 클래스가 포함하는 클래스 중 하나 인 유형의 멤버를 가질 수없는 이유는 무엇입니까?

  21. 21

    함수를 사용하여 동적 배열 크기를 늘리십시오. 무료 오류, 잘못된 다음 크기 (빠름)

  22. 22

    중첩 된 forEach 및 for 루프가있는 함수는 false를 반환하지 않습니다.

  23. 23

    Mongoose의 다른 배열에 중첩 된 배열에 요소를 추가하는 방법은 무엇입니까?

  24. 24

    gcc는 중첩 된 일반 람다를 사용하여이 코드를 수락하고 clang이 거부합니다. 이유는 무엇입니까?

  25. 25

    람다 함수를 사용하여 중첩 된 목록 교차

  26. 26

    중첩 된 sort ()를 사용하여 중첩 된 배열을 정렬 할 수 있습니까?

  27. 27

    jQuery는 함수 매개 변수를 중첩 된 함수로 전달합니다.

  28. 28

    React에서 화살표 함수로 상수로 정의 된 중첩 된 구성 요소를 사용하는 방법은 무엇입니까?

  29. 29

    중첩 된 HashMaps를 사용하는 것이 나쁜 습관입니까?

뜨겁다태그

보관