source

어느 것이 더 빠릅니까?SELECT * 또는 SELECT column1, column2, column3 등

nicesource 2023. 8. 17. 21:26
반응형

어느 것이 더 빠릅니까?SELECT * 또는 SELECT column1, column2, column3 등

그 을 들었습니다.SELECT *으로 SQL 할 때 . SQL 명령어를 작성하는 이 더 입니다. 왜냐하면 더 효율적이기 때문입니다.SELECT필요한 열을 입력합니다.

하다면,SELECT 열은 열 을 사 해 합 니 다 야 용

SELECT * FROM TABLE

또는

SELECT column1, colum2, column3, etc. FROM TABLE

이 경우 효율성이 정말 중요합니까? 생각엔 ㅠㅠSELECT *만약 당신이 정말로 모든 데이터가 필요하다면 내부적으로 더 최적일 것입니다. 하지만 저는 데이터베이스에 대한 실질적인 이해 없이 이 말을 하는 것입니다.

이 경우에 가장 좋은 방법이 무엇인지 궁금합니다.

업데이트: 제가 정말로 하고 싶은 유일한 상황을 명시해야 할 것 같습니다.SELECT *새 열이 추가되더라도 항상 모든 열을 검색해야 한다는 것을 알고 있는 테이블에서 데이터를 선택하는 경우입니다.

하지만 제가 본 반응들을 고려해 볼 때, 이것은 여전히 나쁜 생각인 것 같습니다.SELECT *제가 생각했던 것보다 훨씬 더 기술적인 이유로 절대 사용되어서는 안 됩니다.

특정 열을 선택하는 것이 더 나은 이유 중 하나는 SQL Server가 테이블 데이터를 쿼리하는 대신 인덱스에서 데이터에 액세스할 수 있는 확률을 높이기 때문입니다.

제가 쓴 글은 다음과 같습니다.선택 쿼리의 진짜 이유는 잘못된 인덱스 범위입니다.

또한 데이터를 사용하는 코드는 나중에 테이블 스키마를 변경하더라도 동일한 데이터 구조를 얻을 수 있기 때문에 변경하기가 쉽습니다.

모든 열을 선택한다는 규격을 고려할 때 현재는 거의 차이가 없습니다.그러나 데이터베이스 스키마는 변경됩니다.를 사용하면 테이블에 새 열이 추가됩니다. 코드가 해당 새 데이터를 사용하거나 표시할 준비가 되지 않았을 가능성이 큽니다.이는 시스템이 예상치 못한 성능 및 기능 변경에 노출된다는 것을 의미합니다.

이를 사소한 비용으로 치부할 수도 있지만, 필요 없는 열은 다음과 같아야 합니다.

  1. 데이터베이스에서 읽기
  2. 네트워크를 통해 전송됨
  3. 프로세스에 통합
  4. (ADO형 기술의 경우) 데이터 테이블 인메모리에 저장
  5. 무시 및 폐기 / 가비지 수집

항목 #1에는 잠재적인 커버링 인덱스를 제거하여 데이터 페이지 로드(및 서버 캐시 스레싱)를 유발하고 행/페이지/테이블 잠금을 발생시키는 등 많은 숨겨진 비용이 있습니다.

이 값을 열을 지정할 때 절약되는 잠재적 비용과 비교하면 다음과 같습니다.

  1. 프로그래머가 열을 추가하기 위해 SQL을 다시 방문할 필요가 없습니다.
  2. SQL의 네트워크 전송 속도가 더 빠름
  3. SQL Server 쿼리 구문 분석/검증 시간
  4. SQL Server 쿼리 계획 캐시

항목 1의 경우, 추가할 수 있는 모든 새 열을 사용하도록 코드를 추가/변경하는 것이 현실이므로, 이는 세척입니다.

항목 2의 경우, 다른 패킷 크기 또는 네트워크 패킷 수에 영향을 줄 정도로 차이가 나는 경우는 거의 없습니다.SQL 문 전송 시간이 가장 중요한 문제가 된 경우에는 먼저 문 전송 속도를 줄여야 합니다.

항목 3의 경우 에 대한 확장이 수행되어야 하므로 절약되는 비용이 없습니다. 즉, 테이블 스키마를 참조해야 합니다.열을 나열하는 것은 스키마에 대해 유효성을 검사해야 하기 때문에 현실적으로 동일한 비용이 발생합니다.다른 말로 하면, 이것은 완전한 세척입니다.

항목 4의 경우 특정 열을 지정할 때 쿼리 계획 캐시가 더 커질 수 있지만 지정한 열 집합이 아닌 다른 열 집합을 처리하는 경우에만 가능합니다.이 경우 필요에 따라 다른 계획을 원하기 때문에 다른 캐시 항목을 사용해야 합니다.

따라서 이 모든 것은 질문을 지정한 방식 때문에 스키마가 최종적으로 수정될 경우 문제의 탄력성으로 귀결됩니다.만약 당신이 이 스키마를 ROM에 구울 때, 그것은 완벽하게 받아들여질 수 있습니다.

그러나 일반적인 지침은 필요한 열만 선택해야 한다는 입니다. 즉, 때때로 모든 열을 요청하는 것처럼 보이지만 DBA와 스키마 진화는 쿼리에 큰 영향을 미칠 수 있는 새 열이 나타날 수 있음을 의미합니다.

항상 특정 열을 선택하는 것이 좋습니다.여러분이 하는 일을 계속해서 잘하게 된다는 것을 기억하세요, 그러니 그것을 올바르게 하는 습관을 들이세요.

코드 변경 없이 스키마가 변경될 수 있는 이유가 궁금하다면 감사 로깅, 유효/만료 날짜 및 규정 준수 문제에 대해 DBA가 체계적으로 추가하는 기타 유사한 사항을 고려해 보십시오.시스템 또는 사용자 정의 필드에 있는 다른 곳의 성능에 대한 비공식적인 변경 사항도 있습니다.

필요한 열만 선택해야 합니다.모든 열이 필요한 경우에도 SQL 서버가 시스템 테이블에 열을 쿼리할 필요가 없도록 열 이름을 나열하는 것이 좋습니다.

또한 다른 사용자가 테이블에 열을 추가할 경우 응용프로그램이 손상될 수 있습니다.프로그램에 예상치 못한 열이 표시되고 열을 처리하는 방법을 모를 수 있습니다.

이 외에도 테이블에 이진 열이 있는 경우 쿼리 속도가 훨씬 느리고 네트워크 리소스를 더 많이 사용합니다.

4대 네 .select *나쁜 것입니다.

  1. 가장 중요한 실제 이유는 사용자가 열이 반환되는 순서를 마법처럼 알 수 있도록 하기 때문입니다.명확하게 하는 것이 더 낫습니다. 테이블이 바뀌는 것으로부터 당신을 보호합니다. 그리고 그것은 당신을...

  2. 사용 중인 열 이름이 변경된 경우 더 이상 존재하지 않는 열(또는 이름이 변경된 열 등)을 사용하려고 할 때보다 SQL 호출 지점에서 조기에 검색하는 것이 좋습니다.

  3. 열 이름을 나열하면 코드가 훨씬 더 자체 문서화되므로 가독성이 더 높아집니다.

  4. 네트워크를 통해 전송하는 경우(또는 전송하지 않은 경우에도) 필요 없는 열은 낭비일 뿐입니다.

다른 사용자가 테이블에 열을 추가/삽입해도 응용프로그램에 영향을 미치지 않으므로 열 목록을 지정하는 이 일반적으로 가장 좋은 옵션입니다.

서버의 경우 열 이름을 지정하는 것이 확실히 더 빠릅니다.하지만 만약에

  1. 성능은 큰 문제가 아닙니다(예: 이것은 각 테이블에 수백 또는 수천 개의 행이 있는 웹 사이트 콘텐츠 데이터베이스입니다).
  2. 당신의 일은 복잡한 일회성 애플리케이션을 만드는 것이 아니라 공통 프레임워크를 사용하여 많은 작고 유사한 애플리케이션(예: 공개 콘텐츠 관리 웹 사이트)을 만드는 것입니다.
  3. 유연성이 중요합니다(각 사이트에 대한 db 스키마의 사용자 정의 대신).

그러면 SELECT *를 계속 사용하는 것이 좋습니다 *. 프레임워크에서 SELECT *를 많이 사용하면 새로운 웹 사이트 관리 컨텐츠 필드를 테이블에 도입하여 CMS(버전, 워크플로우/승인 등)의 모든 이점을 제공하는 동시에 수십 개의 포인트가 아닌 몇 개의 포인트에서만 코드를 터치할 수 있습니다.

저는 DB 전문가들이 저를 싫어할 것이라는 것을 알고 있습니다. 저의 세계에서는 개발자 시간이 부족하고 CPU 주기가 풍부하기 때문에 절약하는 것과 낭비하는 것을 적절히 조정합니다.

쿼리가 네트워크를 통해 전송되지 않는 경우에도 SELECT *는 잘못된 방법입니다.

  1. 필요한 것보다 더 많은 데이터를 선택하면 쿼리의 효율성이 떨어집니다. 서버는 추가 데이터를 읽고 전송해야 하므로 시간이 걸리고 시스템에 불필요한 부하를 발생시킵니다(다른 사람들이 언급한 것처럼 네트워크뿐만 아니라 디스크, CPU 등).또한 서버는 쿼리만큼 쿼리를 최적화할 수 없습니다(예: 쿼리에 대해 커버링 인덱스 사용).
  2. 시간이 지나면 테이블 구조가 변경될 수 있으므로 SELECT *는 다른 열 집합을 반환합니다.따라서 애플리케이션이 예기치 않은 구조의 데이터셋을 얻어 다운스트림 어딘가에서 손상될 수 있습니다.열을 명시적으로 지정하면 알려진 구조의 데이터 집합을 가져오거나 데이터베이스 수준에서 명확한 오류(예: '열을 찾을 수 없음')가 발생합니다.

물론 이 모든 것은 작고 단순한 시스템에서는 크게 문제가 되지 않습니다.

지금까지 많은 좋은 이유들이 여기에 답했습니다. 여기 언급되지 않은 또 다른 이유가 있습니다.

기둥의 이름을 명시적으로 지정하면 향후 유지관리에 도움이 됩니다.어느 시점에서 변경하거나 문제를 해결할 때 "도대체 사용된 열이 어디에 있는지"를 묻는 자신을 발견할 수 있습니다.

이름이 명시적으로 나열된 경우, 저장된 모든 절차, 보기 등을 통해 해당 열에 대한 모든 참조를 찾는 것은 간단합니다.DB 스키마에 대한 CREATE 스크립트를 덤프하고 텍스트 검색을 수행합니다.

성능 면에서 특정 열이 있는 선택이 더 빠를 수 있습니다(모든 데이터를 읽을 필요 없음).쿼리가 실제로 모든 열을 사용하는 경우에도 명시적 매개 변수를 사용하는 SELECT가 여전히 선호됩니다.모든 속도 차이는 기본적으로 눈에 띄지 않으며 거의 일정한 시간에 가깝습니다.언젠가 당신의 스키마가 바뀔 것이고, 이것은 이것으로 인한 문제를 예방하는 좋은 보험입니다.

SQL Server가 열을 끌어오기 위해 열을 조회할 필요가 없기 때문에 열을 명확하게 정의할 수 있습니다.열을 정의하면 SQL에서 해당 단계를 건너뛸 수 있습니다.

SQL은 항상 필요한 열을 지정하는 것이 좋습니다. 한 번만 생각해 보면 쿼리할 때마다 "wtf is *"라고 생각할 필요가 없습니다.또한 나중에 다른 사용자가 쿼리에 실제로 필요하지 않은 열을 테이블에 추가할 수도 있으므로 모든 열을 지정하는 것이 좋습니다.

"select*"의 문제는 실제로 필요하지 않은 데이터를 가져올 가능성입니다.실제 데이터베이스 쿼리 중에는 선택한 열이 실제로 계산에 추가되지 않습니다.정말 "무거운" 것은 클라이언트로 데이터를 다시 전송하는 것이며, 실제로 필요하지 않은 열은 네트워크 대역폭을 낭비하고 쿼리가 반환되기를 기다리는 시간을 늘리는 것입니다.

"Select *..."에서 가져온 모든 열을 사용하더라도, 지금은 그것뿐입니다.나중에 테이블/뷰 레이아웃을 변경하고 열을 추가하면 필요 없는 경우에도 선택한 열을 가져오기 시작합니다.

"select *" 문이 잘못된 또 다른 점은 보기 작성입니다."select *"를 사용하여 보기를 작성한 후 나중에 테이블에 열을 추가하면 보기 정의와 반환된 데이터가 일치하지 않으므로 보기를 다시 컴파일해야 다시 작동할 필요가 있습니다.

"선택*"을 쓰는 것이 매력적이라는 것을 압니다. 왜냐하면 저는 제 쿼리에 있는 모든 필드를 수동으로 지정하는 것을 정말 싫어하기 때문입니다. 하지만 여러분의 시스템이 진화하기 시작하면 여러분은 뷰에서 버그를 제거하거나 앱을 최적화하는 것보다 필드를 지정하는 데 더 많은 시간과 노력을 들이는 것이 가치가 있다는 것을 알게 될 것입니다.

열을 명시적으로 나열하는 것이 성능에 도움이 되지만 너무 흥분하지는 마십시오.

따라서 모든 데이터를 사용하는 경우 단순성을 위해 SELECT*를 사용해 보십시오(열이 많고 조인을 수행하는 것을 상상해 보십시오...쿼리가 끔찍해질 수 있습니다.).그런 다음 - 측정합니다.열 이름이 명시적으로 나열된 쿼리와 비교합니다.

성능에 대해 추측하지 말고 측정해 보세요!

명시적 나열은 빅데이터(예: 게시물 본문 또는 기사)가 포함된 열이 있고 지정된 쿼리에 빅데이터가 필요하지 않을 때 가장 유용합니다.그러면 DB 서버가 응답에 반환하지 않음으로써 시간, 대역폭 및 디스크 처리량을 절약할 수 있습니다.쿼리 결과도 더 작아져 모든 쿼리 캐시에 적합합니다.

필요한 필드만 선택하고 필요한 숫자만 선택해야 합니다.

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

데이터베이스 외부에서 동적 쿼리는 주입 공격 및 잘못된 형식의 데이터의 위험을 실행합니다.일반적으로 저장 프로시저 또는 매개 변수화된 쿼리를 사용하여 이 문제를 해결할 수 있습니다.또한 서버는 동적 쿼리가 실행될 때마다 실행 계획을 생성해야 합니다.

모든 필드에 대한 데이터를 가져와야 하는 경우에만 명시적 필드 이름을 사용하는 것이 *보다 빠르지 않습니다.

클라이언트 소프트웨어는 반환되는 필드의 순서에 따라 달라지지 않아야 하므로, 그것도 말도 안 되는 소리입니다.

그리고 어떤 필드가 존재하는지 모르기 때문에 *를 사용하여 모든 필드를 가져와야 할 가능성이 있습니다(매우 동적인 데이터베이스 구조라고 생각).

명시적 필드 이름을 사용할 때의 또 다른 단점은 필드 이름이 많고 필드 이름이 길면 코드 및/또는 쿼리 로그를 읽는 것이 더 어려워진다는 것입니다.

따라서 규칙은 다음과 같습니다. 모든 필드가 필요한 경우 *를 사용하고, 하위 집합만 필요한 경우 명시적으로 이름을 지정하십시오.

결과가 너무 큽니다.SQL 엔진에서 클라이언트로 결과를 생성하고 전송하는 속도가 느립니다.

일반적인 프로그래밍 환경인 클라이언트 측은 행 수가 엄청날 수 있으므로 결과를 필터링하고 처리하도록 설계되어서는 안 됩니다(예: WHERE 절, ORDER 절).

또한 응용프로그램에서 얻을 수 있는 각 열의 이름을 지정하면 사용자의 열이 (순서에 상관없이) 계속 존재하는 한 다른 사용자가 테이블을 변경하더라도 응용프로그램이 중단되지 않습니다.

성능 측면에서 저는 둘 다 같다는 의견을 보았습니다. 하지만 사용성 측면에서는 +와 -가 있습니다.

쿼리에서 (* 선택)을 사용할 때 누군가 테이블을 변경하고 이전 쿼리에 필요하지 않은 새 필드를 추가하면 불필요한 오버헤드가 발생합니다.그리고 새로 추가된 필드가 블롭 또는 이미지 필드라면 어떨까요?그러면 당신의 질의 응답 시간은 정말 느릴 것입니다.

반면 (col1,col2,... 선택)을 사용하고 테이블이 변경되고 새 필드가 추가되면 결과 집합에 해당 필드가 필요한 경우 테이블 변경 후 항상 선택 쿼리를 편집해야 합니다.

하지만 항상 col1, col2를 선택하는 것이 좋습니다...나중에 테이블이 변경되면 쿼리를 변경합니다.

이것은 오래된 게시물이지만 여전히 유효합니다.참고로, 저는 다음과 같은 매우 복잡한 질문을 가지고 있습니다.

  • 테이블 12개
  • 6 왼쪽 조인
  • 9개의 내부 결합
  • 총 108개 열(12개 테이블 모두)
  • 54개의 열만 있으면 됩니다.
  • A 4열 주문 기준 절

Select*를 사용하여 쿼리를 실행하면 평균 2869ms가 소요됩니다.Select를 사용하여 쿼리를 실행하면 평균 1513ms가 소요됩니다.

반환된 총 행 수는 13,949개입니다.

열 이름을 선택하면 Select*보다 성능이 빨라집니다.

* 또는 열을 사용하는 경우 속도 측면에서 동일하게 효율적입니다.

차이는 속도가 아니라 기억력에 관한 것입니다.여러 개의 열을 선택하는 경우 SQL Server는 사용자가 요청한 모든 열에 대한 모든 데이터를 포함하여 쿼리를 처리할 메모리 공간을 할당해야 합니다.

성능 측면에서 중요한 것은 WHERE 조항과 JOIN, OUTER JOIN 등의 수에 크게 의존하는 실행 계획입니다.

질문에는 SELECT *를 사용하십시오. 모든 열이 필요한 경우 성능에 차이가 없습니다.

DB 서버의 버전에 따라 다르지만 최신 버전의 SQL은 어떤 방식으로든 계획을 캐시할 수 있습니다.당신의 데이터 접근 코드로 가장 잘 유지할 수 있는 것은 무엇이든 좋습니다.

원하는 열을 정확히 지정하는 것이 더 나은 한 가지 이유는 테이블 구조의 향후 변경 가능성 때문입니다.

인덱스 기반 접근 방식을 사용하여 데이터 구조를 쿼리 결과로 채우는 수동으로 데이터를 읽는 경우, 앞으로 열을 추가/제거할 때 무엇이 잘못되었는지 파악하는 데 어려움을 겪을 수 있습니다.

무엇이 더 빠른지에 대해서는 다른 사람들의 전문성에 귀를 기울일 것입니다.

대부분의 문제와 마찬가지로, 그것은 여러분이 성취하기를 원하는 것에 달려 있습니다.테이블의 모든 열을 허용하는 DB 그리드를 작성하려면 "Select *"가 정답입니다.그러나 특정 열만 필요로 하고 쿼리에서 열을 추가하거나 삭제하는 경우는 개별적으로 지정합니다.

또한 서버에서 전송할 데이터의 양에 따라 다릅니다.열 중 하나가 메모, 그래픽, 블롭 등으로 정의되어 있고 해당 열이 필요하지 않은 경우 "선택*"을 사용하지 않는 것이 좋습니다. 그렇지 않으면 원하지 않는 데이터가 가득 차서 성능이 저하될 수 있습니다.

다른 모든 사용자가 말한 내용에 추가하기 위해 선택하는 모든 열이 인덱스에 포함된 경우 SQL에서 추가 데이터를 조회하는 대신 인덱스에서 결과 집합을 꺼냅니다.

열 수와 같은 메타데이터를 가져오려면 SELECT *가 필요합니다.

이 때문에 큰 타격을 받겠지만 선택*을 선택합니다. 왜냐하면 거의 모든 데이터가 여러 테이블의 필요한 값을 액세스하기 쉬운 단일 보기로 사전 결합하는 SQL Server Views에서 검색되기 때문입니다.

그런 다음 새 필드가 기본 테이블에 추가될 때 변경되지 않는 보기의 모든 열을 원합니다.이는 데이터 출처를 변경할 수 있는 추가적인 이점이 있습니다.보기의 필드 A를 한 번에 계산한 다음 정적으로 변경할 수 있습니다.어느 쪽이든 뷰가 필드 A를 나에게 제공합니다.

이 기능의 장점은 데이터 계층에서 데이터셋을 가져올 수 있다는 것입니다.그런 다음 그것들을 내 BL로 전달하고, 그것들로부터 객체를 만들 수 있습니다.나의 메인 앱은 객체만 알고 상호 작용합니다.데이터 행을 통과할 때 개체가 자동으로 생성되도록 허용하기도 합니다.

물론 제가 유일한 개발자이기 때문에 그것도 도움이 됩니다 :)

위의 모든 사람들이 말한 것과 더불어:

읽을 수 있는 유지 관리 가능한 코드를 찾고 있는 경우 다음과 같은 작업을 수행합니다.

foo를 선택하고 위젯에서 bar;

즉시 읽을 수 있고 의도를 보여줍니다.그 전화를 하면 무엇을 얻을 수 있는지 알 수 있습니다.위젯에 foo 및 bar 열만 있는 경우 *를 선택하면 반환되는 항목에 대해 생각하고 주문이 올바르게 매핑되었는지 확인해야 하는 등의 작업을 수행할 수 있습니다.그러나 위젯에 더 많은 열이 있지만 foo와 bar에만 관심이 있는 경우 와일드카드를 쿼리한 다음 반환된 일부만 사용하면 코드가 엉망이 됩니다.

또한 정의상 내부 조인이 있는 경우 조인 열의 데이터가 반복되므로 모든 열이 필요하지 않습니다.

SQL 서버에 열을 나열하는 것이 어렵거나 시간이 많이 걸리는 것은 아닙니다.개체 브라우저에서 끌어다 놓기만 하면 됩니다(단어 열에서 끌어다 놓으면 한 번에 모두 얻을 수 있습니다).시스템에 영구적인 성능 저하(인덱스 사용을 줄일 수 있고 네트워크를 통해 불필요한 데이터를 전송하는 데 비용이 많이 들기 때문)를 유발하고 데이터베이스가 변경될 때 예상치 못한 문제가 발생할 가능성을 높이는 것(예를 들어 사용자가 보지 않았으면 하는 열이 추가되기도 함).발달 시간의 분 단위는 근시안적이고 전문적이지 않습니다.

매번 선택할 열을 절대적으로 정의합니다.그렇게 하지 않을 이유가 없으며 성능 향상은 충분히 가치가 있습니다.

"SELECT *" 옵션을 제공하지 말았어야 했습니다.

모든 열이 필요한 경우 SELECT *를 사용하면 되지만 결과를 사용할 때 인덱스가 아닌 이름으로 액세스할 수 있도록 순서가 변경될 수 있습니다.

*가 목록을 가져오려면 어떻게 해야 하는지에 대한 의견은 무시합니다. 이름이 지정된 열을 구문 분석하고 검증하는 것이 처리 시간과 같을 가능성이 높습니다.너무 일찍 최적화하지 마십시오 ;-)

언급URL : https://stackoverflow.com/questions/65512/which-is-faster-best-select-or-select-column1-colum2-column3-etc

반응형