itsource

데이터베이스 테이블의 일부 기록을 확인하는 가장 빠른 방법은?

mycopycode 2023. 10. 24. 21:19
반응형

데이터베이스 테이블의 일부 기록을 확인하는 가장 빠른 방법은?

작업해야 할 큰 테이블이 있습니다. parent_id가 내 통과 값과 동일한 레코드가 있는지 확인하고 싶습니다. 현재 parent_id = :id"인 내 테이블에서 "select count (*)"를 사용하여 이를 구현하는 것입니다. 만약 결과가 0을 초과하면 존재하는 레코드를 의미합니다.

이것은 매우 큰 테이블이기 때문에, 존재하는 레코드의 정확한 수가 몇 개인지는 상관하지 않습니다. 단지 존재 여부를 알고 싶기 때문에 카운트(*)는 다소 비효율적이라고 생각합니다.

이 요구사항을 가장 빠른 방법으로 구현하려면 어떻게 해야 합니까?저는 오라클 10을 사용하고 있습니다.

#

동면 팁 & 트릭 https://www.hibernate.org/118.html#A2 에 의하면요.

다음과 같이 적을 것을 제안합니다.

정수 카운트 = (정수) session.create쿼리("..."에서 카운트(*) 선택").uniqueResult();

여기서 독특한 결과()의 마법이 무엇인지 모르겠습니다. 왜 이렇게 빨리 만들어집니까?

"parent_id = passingId 및 rowrum < 2인 내 테이블에서 1을 선택하십시오"와 비교하면 어떤 것이 더 효율적입니까?

레코드 수에 관심이 없는 경우 EXIST 쿼리를 사용합니다.

select 'Y' from dual where exists (select 1 from mytable where parent_id = :id)

레코드가 존재할 경우 'Y'를 반환하고, 존재하지 않을 경우에는 'Y'를 반환합니다.

[히버네이트의 "유일한 결과"에 대한 질문의 관점에서 보면, 이 모든 것은 반환할 객체가 하나일 때 하나의 객체를 반환하는 것이지, 하나의 객체를 포함하는 집합은 아닙니다.여러 결과가 반환되면 메서드는 예외를 생성합니다.]

다음 항목 간에 실질적인 차이는 없습니다.

select 'y' 
  from dual 
 where exists (select 1 
                 from child_table 
                where parent_key = :somevalue)

그리고.

select 'y' 
  from mytable 
 where parent_key = :somevalue 
   and rownum = 1;

... 최소한 Oracle 10gR2 이상에서는 가능합니다.Oracle은 FAST DUAL 작업을 수행할 수 있을 정도로 현명합니다. 이 릴리스에서 Oracle에 대한 실제 작업을 제로화할 수 있습니다.두 번째 쿼리는 고려 사항이라면 포팅하기가 더 쉬울 것입니다.

실제 성능 차별화 요소는 parent_key 열이 인덱싱되었는지 여부입니다.그렇지 않은 경우 다음과 같은 작업을 실행해야 합니다.

select 'y' 
  from dual 
 where exists (select 1 
                 from parent_able 
                where parent_key = :somevalue)

인덱스가 있는 경우 선택 개수 (*)는 가볍게 빨라야 하며, 없는 경우 첫 번째 일치 후 데이터베이스를 중단하도록 허용해도 큰 도움이 되지 않습니다.

하지만 당신이 물었으니깐

boolean exists = session.createQuery("select parent_id from Entity where parent_id=?")
                        .setParameter(...)
                        .setMaxResults(1)
                        .uniqueResult() 
                 != null;

(이 컴퓨터에서 테스트할 최대 절전 모드가 없으므로 예상되는 구문 오류)

Oracle의 경우 maxResults는 최대 절전 모드에서 로넘으로 변환됩니다.

고유한 Result()의 기능에 관해서는 JavaDoc을 읽어 보십시오!목록 대신 고유한 결과()를 사용해도 성능에 아무런 영향이 없습니다. 올바르게 기억하면 고유한 결과를 실행하면 목록()에 위임합니다.

우선 제 테이블의 인덱스가 필요합니다. parent_id.

이렇게 하면 큰 테이블의 경우에도 쿼리가 충분히 빠릅니다(동일한 parent_id를 가진 행이 많이 존재하지 않는 한).

만약 그렇지 않다면, 당신은 글을 쓸 수 있습니다.

select 1 from mytable where parent_id = :id and rownum < 2

1 행을 포함하는 단일 행을 반환하거나 아예 행을 반환하지 않습니다.행을 셀 필요는 없고, 하나만 찾아서 종료하면 됩니다.그러나 이 SQL은 (로넘 때문에) Oracle 고유 SQL이므로 사용하지 않는 것이 좋습니다.

DB2에는 다음과 같은 것이 있습니다.select * from mytable where parent_id = ? fetch first 1 row only도 비슷한 생각합니다 오라클과 비슷한 것이 있다고 생각합니다.

이 쿼리는 레코드가 있으면 1을 반환하고 그렇지 않으면 0을 반환합니다.

SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2);

테이블 크기나 성능 문제에 관계없이 테이블 데이터 통계를 확인해야 할 때 도움이 될 수 있습니다.

언급URL : https://stackoverflow.com/questions/2131168/the-fastest-way-to-check-if-some-records-in-a-database-table

반응형