Resultset : 인덱스별로 열 값을 검색하는 것과 레이블별로 검색
-
06-07-2019 - |
문제
JDBC를 사용할 때 종종
ResultSet rs = ps.executeQuery();
while (rs.next()) {
int id = rs.getInt(1);
// Some other actions
}
나는 나 자신 (그리고 코드의 저자들)에게 열 값을 검색하기 위해 레이블을 사용하지 않는 이유를 물었다.
int id = rs.getInt("CUSTOMER_ID");
내가 들었던 가장 좋은 설명은 성능에 관한 것입니다. 그러나 실제로 처리가 매우 빠르게 만들어 집니까? 나는 측정을 수행 한 적이 없지만 그렇게 믿지 않습니다. 그럼에도 불구하고 라벨별로 검색하는 것이 약간 느려질지라도 더 나은 가독성과 유연성을 제공합니다.
그렇다면 누군가 열 레이블 대신 열 인덱스로 열 값을 검색하는 것을 피할 수있는 좋은 설명을 할 수 있습니까? 두 가지 접근 방식의 장단점은 무엇입니까 (특정 DBM에 관한)?
해결책
당신은 사용해야합니다 기본적으로 문자열 레이블.
장점 :
- 열 순서의 독립성
- 더 나은 가독성/유지 가능성
단점 :
- 열 이름을 제어 할 수 없습니다 (저장된 절차를 통해 액세스)
어느 걸 더 선호하십니까?
ints?
int i = 1;
customerID = resultSet.getInt (i ++);
CustomerName = resultSet.getString (i ++);
customerAddress = resultSet.getString (i ++);
아니면 문자열?
customerID = resultSet.getInt ( "customer_id");
CustomerName = resultSet.getString ( "customer_name");
customerAddress = resultSet.getString ( "customer_address");
위치 1에 새 열이 삽입되면 어떻게됩니까? 어떤 코드를 선호 하시겠습니까? 또는 열의 순서가 변경된 경우 어떤 코드 버전을 전혀 변경해야합니까?
그것이 당신이 사용해야하는 이유입니다 기본적으로 문자열 레이블.
다른 팁
경고 : 나는 여기서 폭발 할 것입니다. 왜냐하면 이것이 나를 미치게 만들기 때문입니다.
시간의 99%*, 사람들이 모호한 아이디어를 가지고 있다는 것은 말도 안되는 미세 최적화입니다. 이것은 수백만 개의 SQL 결과에 걸쳐 매우 빡빡하고 바쁜 루프에 있지 않는 한 완전히 무시합니다. 항상, 희망적으로 드물게, 당신은 그것을 눈치 채지 못할 것입니다. 그렇게하지 않는 모든 사람에게는 열 인덱싱에서 메인 타기, 업데이트 및 수정의 개발자 시간 비용이 무한한 외형 적용 애플리케이션에 대한 하드웨어의 증분 비용보다 훨씬 큽니다.
이와 같은 최적화를 코드하지 마십시오. 그런 다음 관찰, 측정, 분석 및 최적화. 다시 관찰하고, 다시 측정하고, 다시 분석하고, 다시 최적화하십시오.
최적화는 첫 번째가 아니라 개발의 마지막 단계입니다.
* 그림이 구성됩니다.
그 대답은 그럼에도 불구하고, 여기에 내가 보지 못한 몇 가지 추가 정보와 개인적인 경험이 있습니다.
일반적으로 열 이름 (상수와 리터럴이 아닌 상수가 선호 됨)을 사용하십시오. 이것은 더 명확하고 유지하기가 더 쉽고 향후 변화가 코드를 깨뜨릴 가능성이 적습니다.
그러나 열 인덱스에 사용됩니다. 어떤 경우에는 이것들이 더 빠르지 만 이름의 위의 이유를 무시 해야하는 경우는 충분하지 않습니다. 이들은 도구와 일반적인 방법을 다룰 때 매우 가치가 있습니다. ResultSet
에스. 마지막으로, 열에 이름이 없거나 (예 : 이름이없는 집계)가 없거나 중복 이름이 없으므로 두 가지를 참조 할 수있는 쉬운 방법이 없기 때문에 색인이 필요할 수 있습니다.
*일부 JDBC 드라이버를 작성했으며 일부 오픈 소스 내부를보고 내부적 으로이 열 인덱스를 사용하여 결과 열을 참조합니다. 내가 함께 일한 모든 경우에 내부 드라이버는 먼저 열 이름을 색인에 매핑합니다. 따라서 열 이름은 모든 경우에 항상 더 오래 걸린다는 것을 쉽게 알 수 있습니다. 그러나 이것은 모든 드라이버에게는 사실이 아닐 수도 있습니다.
Java 문서에서 :
결과 세트 인터페이스는 현재 행에서 열 값을 검색하기 위해 getter 메소드 (getboolean, getlong 등)를 제공합니다. 열의 인덱스 번호 또는 열의 이름을 사용하여 값을 검색 할 수 있습니다. 일반적으로 열 인덱스를 사용하는 것이 더 효율적입니다. 열은 1에서 번호가 매겨집니다. 최대 이식성을 위해 각 행 내의 결과 세트 열은 왼쪽에서 오른쪽으로 순서로 읽어야하며 각 열은 한 번만 읽어야합니다.
물론 각 방법 (명명 또는 색인)이 그 자리에 있습니다. 이름이 지정된 열이 기본값이어야한다는 데 동의합니다. 그러나 수많은 루프가 필요한 경우, 선택 문이 동일한 코드 (또는 클래스)의 동일한 섹션에서 정의되고 유지되는 경우 인덱스가 정상적이어야합니다. 단순히 선택된 열을 나열하는 것이 좋습니다. 테이블 변경이 코드를 중단하기 때문에 "선택 *에서 ..."를 선택하십시오.
물론, 열 이름을 사용하면 건식이 높아지고 유지 보수가 쉬워집니다. 그러나 열 이름을 사용하면 플립 사이드가 있습니다. 아시다시피, SQL은 동일한 이름의 여러 열 이름을 허용하므로 getter resultset 메소드에서 입력 한 열 이름이 실제로 액세스하려는 열 이름을 가리 킵니다. 이론적으로 열 이름 대신 인덱스 번호를 사용하는 것은 사전이지만 가독성이 줄어 듭니다 ...
감사
라벨을 사용하는 것이 성능에 큰 영향을 미치지 않는다고 생각합니다. 그러나 사용하지 말아야 할 또 다른 이유가 있습니다 String
에스. 또는 int
S, 그 문제에 대해.
상수 사용을 고려하십시오. 사용 int
상수는 코드를보다 읽기 쉽지만 오류가 발생할 가능성이 적습니다.
더 읽기 쉬운 것 외에도 상수는 라벨 이름으로 오타를 만드는 것을 방지합니다. 컴파일러는 오류가 발생합니다. 그리고 모든 IDE의 가치는 무엇이든 그것을 선택할 것입니다. 사용하는 경우에는 그렇지 않습니다 String
s 또는 ints
.
Oracle 데이터베이스 에서이 정확한 주제에 대해 성능 프로파일 링을했습니다. 코드에는 수많은 콜럼과 수많은 행이있는 결과 세트가 있습니다. 20 초 중 ((!) 요청은 메소드를 실행하는 데 걸립니다.
분명히 전체 디자인에는 문제가 있지만 열 이름 대신 인덱스를 사용하면 아마도 4 초가 걸릴 것입니다.
당신은 둘 다 최선을 다할 수 있습니다! 열 이름을 사용하는 유지 관리 및 보안과 함께 인덱스를 사용하는 속도.
먼저 - 결과 세트를 통해 루프를하지 않는 한 열 이름 만 사용하십시오.
액세스 할 각 열당 정수 변수 세트를 정의하십시오. 변수의 이름에는 열의 이름이 포함될 수 있습니다 : 예 : ILAST_NAME.
결과 세트 전에 루프는 열 메타 데이터를 통해 반복하고 각 정수 변수의 값을 해당 열 이름의 열 인덱스로 설정합니다. 'last_name'열의 인덱스가 3 인 경우 'ilast_name'의 값을 3으로 설정하십시오.
결과 세트 루프에서는 Get/Set 메소드에서 정수 변수 이름을 사용하십시오. 변수 이름은 액세스중인 실제 열 이름에 대한 개발자/관리자에게 시각적 단서이지만 값은 열 인덱스이며 최상의 성능을 제공합니다.
참고 : 초기 매핑 (즉, 인덱스 매핑의 열 이름)은 루프의 모든 레코드와 열이 아닌 루프 전에 한 번만 수행됩니다.
JDBC 드라이버는 열이 인덱스 조회를 처리합니다. 따라서 열 이름별로 값을 추출하면 드라이버가 열을 만들기 위해 (일반적으로 해시 맵) 열 이름의 해당 색인을 확인합니다.
나는 성능이 우리가 접근 방식 중 하나를 선택하도록 강요 할 수있는 것이 아니라는 이전 답변에 동의합니다. 대신 다음 사항을 고려하는 것이 좋습니다.
- 코드 가독성 : 모든 개발자에 대해 코드 레이블을 읽는 것은 인덱스보다 훨씬 더 의미가 있습니다.
- 유지 보수 : SQL 쿼리와 유지 관리 방식을 생각해보십시오. SQL 쿼리를 수정/개선/리팩토링 한 후 귀하의 경우에 발생할 가능성이 더 높습니다. 추출 된 열 순서 변경 또는 결과 열 이름 변경. 추출 된 열의 순서를 변경하는 것으로 보입니다 (결과 세트에서 새 열을 추가/삭제 한 결과)가 발생할 가능성이 더 높습니다.
- 캡슐화 : 선택하는 방식에도 불구하고 SQL 쿼리를 실행하는 코드를 격리하고 동일한 구성 요소를 설정 하고이 구성 요소 만 열 이름과 인덱스에 대한 매핑에 대해 알리도록합니다 (사용하기로 결정한 경우 ).
색인을 사용하는 것은 최적화 시도입니다.
이에 의해 저장된 시간은 추가 노력으로 낭비됩니다. 개발자는 변경 후 코드가 올바르게 작동하는지 확인하기 위해 필요한 데이터를 찾아야합니다.
텍스트 대신 숫자를 사용하는 것은 우리의 내장 본능이라고 생각합니다.
레이블에 대한지도에서 조회하는 것 외에도 추가 문자열 생성으로 이어집니다. 스택에서는 발생하지만 여전히 비용이 듭니다.
그것은 모두 개인의 선택에 달려 있으며 지금까지 나는 색인 만 사용했습니다 :-)
다른 포스터가 지적했듯이, 당신이 그렇게하지 않을 정말 강력한 이유가 없다면 열 이름을 고수 할 것입니다. 예를 들어 쿼리 최적화와 비교할 때 성능의 영향은 무시할 수 있습니다. 이 경우 유지 보수는 작은 옵트미즈보다 훨씬 중요합니다.