복붙노트

[SQL] 행의 PostgreSQL에있는 경우 빠른 검사

SQL

행의 PostgreSQL에있는 경우 빠른 검사

나는 테이블에 삽입 할 필요가 행의 무리가 있지만, 이러한 삽입은 항상 일괄 적으로 수행됩니다. 그럼 내가 알고 있기 때문에 내가 배치에서 단일 행이 테이블에 존재하는지 확인하려는 그래서 그들은 모두 삽입되었다.

그하지 기본 키 체크 그래서,해야하지만 너무 많이 중요하지. 같은 그 뭔가 같아요 존재하므로 (*) 카운트가 아마 좋지 않다 그래서 나는 단지 하나의 행을 확인하고 싶습니다.

내가 PostgreSQL의 I에 비교적 새로운 해요하지만 이후 오히려 아는 사람에게 물어 것입니다.

내 배치는 다음과 같은 구조의 행이 포함되어 있습니다 :

userid | rightid | remaining_count

테이블이 제공하는 사용자 ID가있는 행을 포함 그렇다면 그들이 모든 존재가있는 것을 의미한다.

해결법

  1. ==============================

    1.사용하여이 TRUE / FALSE 반환을위한 핵심 단어를 존재합니다

    사용하여이 TRUE / FALSE 반환을위한 핵심 단어를 존재합니다

    select exists(select 1 from contact where id=12)
    
  2. ==============================

    2.방법에 대해 간단하게 :

    방법에 대해 간단하게 :

    select 1 from tbl where userid = 123 limit 1;
    

    (123)는 삽입에 대한 걸 배치의 사용자 ID입니다.

    위의 쿼리는 주어진 사용자 ID 레코드가 있는지 여부에 따라 빈 세트 또는 단일 행 중 하나를 반환합니다.

    이 너무 느린 것으로 판명되면, 당신은 tbl.userid에 인덱스를 생성에 볼 수 있었다.

    프로그램이 중단 중반 배치를 얻는 경우에 이것이 사실조차 유지하기 위해, 나는 당신이 있는지 확인하십시오 당신이 적절하게 데이터베이스 트랜잭션을 관리하는 것이 좋습니다 것 (즉, 배치 전체가 하나의 트랜잭션 내에서 삽입 가져옵니다).

  3. ==============================

    3.

    INSERT INTO target( userid, rightid, count )
      SELECT userid, rightid, count 
      FROM batch
      WHERE NOT EXISTS (
        SELECT * FROM target t2, batch b2
        WHERE t2.userid = b2.userid
        -- ... other keyfields ...
        )       
        ;
    

    BTW : 당신은 중복의 경우 실패 할 전체 배치를 원하는 경우, 다음 (기본 키 제약 조건 부여)

    INSERT INTO target( userid, rightid, count )
    SELECT userid, rightid, count 
    FROM batch
        ;
    

    당신이 원하는 것을 정확히 할 것입니다 것은 : 중 하나가 성공하거나 실패합니다.

  4. ==============================

    4.

    select true from tablename where condition limit 1;
    

    나는이 쿼리가 있다고 생각 외래 키를 확인하기위한 포스트 그레스 사용.

    귀하의 경우에는, 당신도 한 번에이 작업을 수행 할 수 있습니다 :

    insert into yourtable select $userid, $rightid, $count where not (select true from yourtable where userid = $userid limit 1);
    
  5. ==============================

    5.@MikeM는 지적했다.

    @MikeM는 지적했다.

    select exists(select 1 from contact where id=12)
    

    접촉에 인덱스로, 보통 1 MS에 시간 비용을 줄일 수 있습니다.

    CREATE INDEX index_contact on contact(id);
    
  6. ==============================

    6.

    SELECT 1 FROM user_right where userid = ? LIMIT 1
    

    당신의 결과 집합 행을 포함하는 경우 당신은 삽입 할 필요가 없습니다. 그렇지 않으면 레코드를 삽입.

  7. ==============================

    7.당신이 성능에 대해 생각한다면, 당신은 사용하려면이 같은 함수에 "를 수행"할 수 있습니다 :

    당신이 성능에 대해 생각한다면, 당신은 사용하려면이 같은 함수에 "를 수행"할 수 있습니다 :

     PERFORM 1 FROM skytf.test_2 WHERE id=i LIMIT 1;
      IF FOUND THEN
          RAISE NOTICE ' found record id=%', i;  
      ELSE
          RAISE NOTICE ' not found record id=%', i;  
     END IF;
    
  8. ==============================

    8.내가 특별히 당신의 문장을 해결하기 위해 다른 생각을 제안하고 싶습니다 : "나는 그들 모두가 삽입 된 알 다음 있기 때문에 배치에서 하나의 행이 테이블에 존재하는지 확인하고자 그래서."

    내가 특별히 당신의 문장을 해결하기 위해 다른 생각을 제안하고 싶습니다 : "나는 그들 모두가 삽입 된 알 다음 있기 때문에 배치에서 하나의 행이 테이블에 존재하는지 확인하고자 그래서."

    당신은 "배치"에 삽입하지만 한 번에 존재 검사를 하나 개의 레코드를 수행하여 것들을 효율적으로 만들고있다? 이것은 나에게 카운터 직관적 인 것 같다. 당신이 말할 때 그래서 당신은 당신이 하나의 INSERT 문으로 여러 레코드를 삽입하는 의미 나는 그것을 가지고 "삽입은 항상 일괄 적으로 수행됩니다." 당신은 포스트 그레스는 ACID의 준수 것을 깨닫게해야합니다. 당신이 문 삽입 하나에 여러 레코드 (데이터의 배치)를 삽입하는 경우, 일부를 삽입하거나되지 않은 경우 확인 할 필요가 없습니다. 문 중 하나를 통과하거나 실패합니다. 모든 기록은 삽입하거나 아무도됩니다.

    당신의 C # 코드는 단순히 "설정"을하고있는 경우 반면에, 별도의 삽입 문은, 예를 들어, 루프에서, 당신의 마음에,이 "다음 사실로 설명하지해야 ..."배치 "입니다 삽입은 항상 "일괄 적으로 수행됩니다. 당신이, 당신이 검사에 대한 필요성을 느낄 따라서, "배치"전화를 실제로 삽입 될 수 있으며, 어떤 부분을 기대하고 있다는 사실은 강력하게이 좀 더 근본적인 문제가있는 경우에 경우입니다 제안합니다. 당신은 하나 개의 삽입으로 여러 레코드를 삽입 실제로 당신의 패러다임을 변경하고 개인 기록을 만든 경우 확인 지내다 필요가있다.

    이 예제를 생각해 봅시다 :

    CREATE TABLE temp_test (
        id SERIAL PRIMARY KEY,
        sometext TEXT,
        userid INT,
        somethingtomakeitfail INT unique
    )
    -- insert a batch of 3 rows
    ;;
    INSERT INTO temp_test (sometext, userid, somethingtomakeitfail) VALUES
    ('foo', 1, 1),
    ('bar', 2, 2),
    ('baz', 3, 3)
    ;;
    -- inspect the data of what we inserted
    SELECT * FROM temp_test
    ;;
    -- this entire statement will fail .. no need to check which one made it
    INSERT INTO temp_test (sometext, userid, somethingtomakeitfail) VALUES
    ('foo', 2, 4),
    ('bar', 2, 5),
    ('baz', 3, 3)  -- <<--(deliberately simulate a failure)
    ;;
    -- check it ... everything is the same from the last successful insert ..
    -- no need to check which records from the 2nd insert may have made it in
    SELECT * FROM temp_test
    

    이 사실은 그냥 ACID 준수 DB에 대한 패러다임 ..하지 PostgreSQL을합니다. 당신이 당신의 "배치"개념 피하기는 처음에 열을 확인하여 어떤 행을 할 필요 해결하는 경우 즉 당신은 더 나은 꺼져 있습니다.

  9. from https://stackoverflow.com/questions/7471625/fastest-check-if-row-exists-in-postgresql by cc-by-sa and MIT license