복붙노트

[SQL] 결과를 사용할 수까지 여러 건의 SELECT를 시도하는 방법?

SQL

결과를 사용할 수까지 여러 건의 SELECT를 시도하는 방법?

내가 감소하는 정밀, 예를 들어있는 테이블에서 하나의 행을 검색하려는 경우 이 같은 :

SELECT * FROM image WHERE name LIKE 'text' AND group_id = 10 LIMIT 1

이 나에게 어떤 결과를 제공하지 않는 경우,이 하나를 시도해보십시오 :

SELECT * FROM image WHERE name LIKE 'text' LIMIT 1

이 나에게 어떤 결과를 제공하지 않는 경우 그리고,이 하나를 시도해보십시오 :

SELECT * FROM image WHERE group_id = 10 LIMIT 1

그것은 단지 하나의 표현으로 그렇게 할 수 있습니까?

내가 예를 들어,하지이 있지만,이 경우에도 문제가 발생한다 세 개 이상의 검색 매개 변수. 그에 대한 일반적인 해결책이 있습니까? 검색 결과의 관련성으로 분류되는 경우 물론이 편리합니다.

해결법

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

    1.와일드 카드 문자가없는 LIKE는 = 동일합니다. 실제로 이름 = '텍스트'를 의미 가정.

    와일드 카드 문자가없는 LIKE는 = 동일합니다. 실제로 이름 = '텍스트'를 의미 가정.

    인덱스는 성능의 핵심입니다.

    CREATE TABLE image (
      image_id serial PRIMARY KEY
    , group_id int NOT NULL
    , name     text NOT NULL
    );
    

    이상적으로, 당신은 두 개의 인덱스 (기본 키 외에)를 만들 :

    CREATE INDEX image_name_grp_idx ON image (name, group_id);
    CREATE INDEX image_grp_idx ON image (group_id);
    

    두 번째는 데이터 분배 및 다른 세부 사항에 따라 필요하지 않을 수도있다. 여기에 설명 :

    이 사건에 대한 가장 빠른 쿼리해야합니다 :

    SELECT * FROM image WHERE name = 'name105' AND group_id = 10
    UNION ALL
    SELECT * FROM image WHERE name = 'name105'
    UNION ALL
    SELECT * FROM image WHERE group_id = 10
    LIMIT  1;
    

    SQL 바이올린.

    한계 절은 전체 쿼리에 적용됩니다. 포스트 그레스는 LIMIT를 충족하기에 충분한 행을 발견했다하자마자 UNION ALL 이후 다리를 실행하지 스마트 충분하다. 따라서, 쿼리의 첫번째 SELECT의 일치의 출력은 다음과 같습니다 분석 EXPLAIN (오른쪽으로 스크롤!)

    Limit  (cost=0.00..0.86 rows=1 width=40) (actual time=0.045..0.046 rows=1 loops=1)
      Buffers: local hit=4
      ->  Result  (cost=0.00..866.59 rows=1002 width=40) (actual time=0.042..0.042 rows=1 loops=1)
            Buffers: local hit=4
            ->  Append  (cost=0.00..866.59 rows=1002 width=40) (actual time=0.039..0.039 rows=1 loops=1)
                  Buffers: local hit=4
                  ->  Index Scan using image_name_grp_idx on image  (cost=0.00..3.76 rows=2 width=40) (actual time=0.035..0.035 rows=1 loops=1)
                        Index Cond: ((name = 'name105'::text) AND (group_id = 10))
                        Buffers: local hit=4
                  ->  Index Scan using image_name_grp_idx on image  (cost=0.00..406.36 rows=500 width=40) (never executed)
                        Index Cond: (name = 'name105'::text)
                  ->  Index Scan using image_grp_idx on image  (cost=0.00..406.36 rows=500 width=40) (never executed)
                        Index Cond: (group_id = 10)
    Total runtime: 0.087 ms

    굵게 강조 광산.

    ORDER BY 절을 추가하지 마십시오,이 효과를 무효로한다. 그런 다음 포스트 그레스는 상단 행을 반환하기 전에 모든 행을 고려해야 할 것이다.

    이것은 일반적인 솔루션입니다. 당신이 원하는대로 많은 SELECT 문으로 추가합니다.

    정렬 보이드 LIMIT 1. 종류와 그 결과에 하나의 행이 있습니다.

  2. ==============================

    2.늦은 있고 난 전체 솔루션을 쓰는 기분이 안,하지만 난이 필요한 경우 아마 (당신의 필요가 무엇인지에 따라 다름) 고객 유형, 레코드 또는 테이블을 반환 고객 함수를 만들 것입니다. 이것의 장점은 당신이 당신의 기록을 발견하면, 당신은 막을 수 있다는 것이다.

    늦은 있고 난 전체 솔루션을 쓰는 기분이 안,하지만 난이 필요한 경우 아마 (당신의 필요가 무엇인지에 따라 다름) 고객 유형, 레코드 또는 테이블을 반환 고객 함수를 만들 것입니다. 이것의 장점은 당신이 당신의 기록을 발견하면, 당신은 막을 수 있다는 것이다.

    동적 PARAMS의 수를 만들기가 좀 더 도전 할 것입니다. 당신의 PostgreSQL 버전 (그리고 사용 가능한 확장)에 따라, 당신은 hstore 또는 JSON을 전달하고 동적으로 쿼리를 작성 할 수 있습니다.

    어쩌면 가장 큰 SO의 대답은하지만 생각 댓글 잘하면 어떤 음식보다 더.

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

    3.난 당신이 원하는 결과를 찾을 때까지 별도로 쿼리를 실행하는 아무것도 잘못이라고 생각하지 않습니다. 하나 개의 쿼리로 이러한 결합하는 방법이 있지만까지 그 끝은 더 당신이 원하는 무엇을하지 않은, 느린 복잡하고된다.

    난 당신이 원하는 결과를 찾을 때까지 별도로 쿼리를 실행하는 아무것도 잘못이라고 생각하지 않습니다. 하나 개의 쿼리로 이러한 결합하는 방법이 있지만까지 그 끝은 더 당신이 원하는 무엇을하지 않은, 느린 복잡하고된다.

    당신은 당신이 일관된 결과를 얻을 수 있으며 반복 트랜잭션을 설정하는 오버 헤드를 피하기 때문에, 아마 최고의 반복-읽기 격리 수준에서, 하나의 트랜잭션 내에서 모든 쿼리를 실행 해보십시오 실행해야합니다. 또한 당신이 준비된 명령문의 현명한 사용을 할 경우, 당신은 하나 명의 결합 된 성명에서 세 개의 쿼리를 실행하는 것과 거의 같은 오버 헤드를해야합니다.

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

    4.

    SELECT *, 
    CASE WHEN name like 'text' AND group_id = 10 THEN 1
    WHEN name like 'text' THEN 2
    WHEN group_id = 10 THEN 3
    ELSE 4
    END ImageRank
    FROM image
    WHERE ImageRank <> 4
    ORDER BY ImageRank ASC
    LIMIT 1
    

    이것은 의사 솔루션 접근 방식이 될 것입니다하지만 난 당신의 시나리오에서 구문이 허용한다면 완전히 확실하지 않다

  5. from https://stackoverflow.com/questions/14339715/way-to-try-multiple-selects-till-a-result-is-available by cc-by-sa and MIT license