복붙노트

[SQL] 선택 *를 사용하지 않는 이유는 무엇입니까?

SQL

선택 *를 사용하지 않는 이유는 무엇입니까?

나는 사람들의 숫자가 특별히 당신이 당신의 선택 쿼리에서 원하는 각 열 이름을 지정해야한다고 주장 보았다.

어쨌든 모든 열을 사용하는거야 가정, 내가 왜 SELECT *를 사용하지 않을까요?

심지어 질문을 고려 * SQL 쿼리 - 선택 *보기 또는 선택 COL1, COL2에서 ... colN이보기 *에서, 나는 약간 다른 관점에서 문제에 접근하고있어 같은이 정확한 중복 생각하지 않습니다.

우리의 원칙 중 하나는 그것의 시간 전에 최적화하지 않는 것입니다. 그걸 염두에두고, 그것은이 자원 문제를 입증 또는 스키마가 돌 거의 집합입니다 때까지 선호되는 방법이어야한다 SELECT *를 사용하는 것 같다. 어느, 우리가 아는 한 개발이 완전히 완료 될 때까지 발생하지 않습니다.

즉 SELECT *를 사용하지에 우선하는 문제가 말했다?

해결법

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

    1.조기 최적화하지 않는 인용의 본질은 단순하고 간단 코드를 이동 한 다음 다음 효율적으로 최적화 할 수 있습니다 핫스팟을 지적하기 위해 프로파일 러를 사용하는 것입니다.

    조기 최적화하지 않는 인용의 본질은 단순하고 간단 코드를 이동 한 다음 다음 효율적으로 최적화 할 수 있습니다 핫스팟을 지적하기 위해 프로파일 러를 사용하는 것입니다.

    당신은 당신이하고 있는지 확인이 불가능 프로파일 * 선택 사용할 때 따라서 당신은 명확한 및 간단한 코드를 작성하지 않는 당신은 인용의 정신에 대한 것입니다. 선택 * 안티 패턴이다.

    열을 선택하는 것은시기 상조 최적화되지 않습니다 그래서. 내 머리 위로 떨어져 몇 가지 ....

    추론 선택 *를 사용하는 것입니다 ...

    올바른 SQL을 작성하는 것은 그냥 쉽게 선택 *을 쓰기로한다. 진짜 게으른 사람이 적절한 SQL을 기록 그래서 그들은 코드를 다시 방문하고 그들이 그것을했을 때 그들이 뭘하고 있었는지 기억하려고하지 않기 때문에. 그들은 DBA의 코드의 모든 비트에 대해에게 설명하고 싶지 않아요. 그들은 왜 응용 프로그램이 실행 개처럼 그들의 고객에게 설명하고 싶지 않아요.

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

    2.코드가 특정 순서에있는 컬럼에 의존하는 경우, 코드는 테이블에 변경이있을 때 중단됩니다. 당신이 * 선택하면 또한, 테이블의 바이너리 필드가 특히 테이블에서 너무 많이 가져 오는 할 수있다.

    코드가 특정 순서에있는 컬럼에 의존하는 경우, 코드는 테이블에 변경이있을 때 중단됩니다. 당신이 * 선택하면 또한, 테이블의 바이너리 필드가 특히 테이블에서 너무 많이 가져 오는 할 수있다.

    이제 모든 열을 사용해서, 그것은 다른되지 평균 누군가가 테이블에 여분의 열을 추가하지 않을 않습니다.

    이 *에 어떤 열 알고 테이블에 대한 메타 데이터를 가져 오기 위해이 있기 때문에 또한 계획 실행 캐싱 오버 헤드를 추가합니다.

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

    3.하나의 주요 이유는 혹시 추가하면 / 데이터의 SELECT * 전화는 이제 점점됩니다 더 많거나 적은 열을 만드는 테이블, 어떤 쿼리 / 절차에서 제거 열이 예상보다 때문이다.

    하나의 주요 이유는 혹시 추가하면 / 데이터의 SELECT * 전화는 이제 점점됩니다 더 많거나 적은 열을 만드는 테이블, 어떤 쿼리 / 절차에서 제거 열이 예상보다 때문이다.

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

    4.AT 시간 쿼리를 썼는지 존재하는 테이블의 모든 열을 필요로 반대 명시 적으로 테이블의 모든 열을 필요로 할 때. 예를 들어, 당신이 그 방법을 사용할 수 있습니다 (그들이 할 일이 무엇이든) 테이블의 전체 내용을 표시하는 데 필요한한다는 DB 관리 응용 프로그램을 작성했다.

    AT 시간 쿼리를 썼는지 존재하는 테이블의 모든 열을 필요로 반대 명시 적으로 테이블의 모든 열을 필요로 할 때. 예를 들어, 당신이 그 방법을 사용할 수 있습니다 (그들이 할 일이 무엇이든) 테이블의 전체 내용을 표시하는 데 필요한한다는 DB 관리 응용 프로그램을 작성했다.

  5. ==============================

    5.몇 가지 이유가 있습니다 :

    몇 가지 이유가 있습니다 :

    참고 :이 4 바이트의 고정 된 크기를 가지고 있기 때문에 내가 위의 예에서 INTEGER를 선택했다.

  6. ==============================

    6.(열을 제거 말) 응용 프로그램이 SELECT * 데이터를 가져오고 데이터베이스의 테이블 구조가 변경되면 응용 프로그램이 누락 된 필드를 참조하는 모든 장소에 실패합니다. 대신 쿼리에 모든 열을 포함하는 경우, 당신은 응용 프로그램을 쉽게 수정하고, 처음에 데이터를 얻을 (희망) 한 곳에서 휴식 것입니다.

    (열을 제거 말) 응용 프로그램이 SELECT * 데이터를 가져오고 데이터베이스의 테이블 구조가 변경되면 응용 프로그램이 누락 된 필드를 참조하는 모든 장소에 실패합니다. 대신 쿼리에 모든 열을 포함하는 경우, 당신은 응용 프로그램을 쉽게 수정하고, 처음에 데이터를 얻을 (희망) 한 곳에서 휴식 것입니다.

    그 존재는 SELECT *는 것이 바람직한 상황이 다수 존재했다. 하나는 내가 (예를 들어, DB2에 SQL Server와 같은) 다른 데이터베이스에 전체 테이블을 복제 할 필요가 나는 모든 시간을 발생하는 상황이다. 또 다른 (즉, 임의의 특정 테이블의 지식없이) 일반적으로 디스플레이 테이블에 기록 된 응용 프로그램이다.

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

    7.나는 SQL Server 2005에서 뷰를 선택 *를 사용할 때 사실은 이상한 행동을 발견.

    나는 SQL Server 2005에서 뷰를 선택 *를 사용할 때 사실은 이상한 행동을 발견.

    다음 쿼리를 실행하고 당신은 내가 무슨 뜻인지 볼 수 있습니다.

    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
    DROP TABLE [dbo].[starTest]
    CREATE TABLE [dbo].[starTest](
        [id] [int] IDENTITY(1,1) NOT NULL,
        [A] [varchar](50) NULL,
        [B] [varchar](50) NULL,
        [C] [varchar](50) NULL
    ) ON [PRIMARY]
    
    GO
    
    insert into dbo.starTest
    select 'a1','b1','c1'
    union all select 'a2','b2','c2'
    union all select 'a3','b3','c3'
    
    go
    IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vStartest]'))
    DROP VIEW [dbo].[vStartest]
    go
    create view dbo.vStartest as
    select * from dbo.starTest
    go
    
    go
    IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vExplicittest]'))
    DROP VIEW [dbo].[vExplicittest]
    go
    create view dbo.[vExplicittest] as
    select a,b,c from dbo.starTest
    go
    
    
    select a,b,c from dbo.vStartest
    select a,b,c from dbo.vExplicitTest
    
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
    DROP TABLE [dbo].[starTest]
    CREATE TABLE [dbo].[starTest](
        [id] [int] IDENTITY(1,1) NOT NULL,
        [A] [varchar](50) NULL,
        [B] [varchar](50) NULL,
        [D] [varchar](50) NULL,
        [C] [varchar](50) NULL
    ) ON [PRIMARY]
    
    GO
    
    insert into dbo.starTest
    select 'a1','b1','d1','c1'
    union all select 'a2','b2','d2','c2'
    union all select 'a3','b3','d3','c3'
    
    select a,b,c from dbo.vStartest
    select a,b,c from dbo.vExplicittest
    

    지난 2 선택 명령문의 결과를 비교. 나는 당신이 볼하는 대신 이름의 인덱스 열을 참조 * 선택의 결과 믿습니다.

    뷰를 다시하면 다시 잘 작동합니다.

    편집하다

    나는 대 별도의 질문 * "테이블에서 선택 *"을 추가 한 자세한 내용에서 그 행동에 대한 모습에 SQL 서버 2005 * 흥미로운 행동 "테이블에서 등 COLA, COLB을 선택".

  8. ==============================

    8.두 테이블을 조인하고 두 번째 테이블에서 열 A를 사용할 수 있습니다. 나중에 (이름은 같지만 아마도 다른 의미로) 첫 번째 테이블에 A 열의를 추가하는 경우 가능성이 가장 높은 첫 번째 테이블 및 이전으로하지 두 번째의 값을 얻을 수 있습니다. 명시 적으로 선택하려는 열을 지정하는 경우, 그것은 일어나지 않을 것입니다.

    두 테이블을 조인하고 두 번째 테이블에서 열 A를 사용할 수 있습니다. 나중에 (이름은 같지만 아마도 다른 의미로) 첫 번째 테이블에 A 열의를 추가하는 경우 가능성이 가장 높은 첫 번째 테이블 및 이전으로하지 두 번째의 값을 얻을 수 있습니다. 명시 적으로 선택하려는 열을 지정하는 경우, 그것은 일어나지 않을 것입니다.

    당신이 모든 선택 절에 새 열을 추가하는 것을 잊지 경우 열을 지정 물론 때때로 버그가 발생합니다. 새 열은 쿼리가 실행될 때마다 필요하지 않은 경우 버그가 발견되기 전에, 그것은 시간이 걸릴 수 있습니다.

  9. ==============================

    9.난 당신이 조기 최적화에 관한거야,하지만 그건 정말 만 점에 어디로 알고 있습니다. 의도는 처음에 불필요한 최적화를 방지하는 것입니다. 당신의 테이블은 인덱싱되지 않은 있습니까? 당신은 우편 번호를 저장하기 위해 NVARCHAR (4000)를 사용 하시겠습니까?

    난 당신이 조기 최적화에 관한거야,하지만 그건 정말 만 점에 어디로 알고 있습니다. 의도는 처음에 불필요한 최적화를 방지하는 것입니다. 당신의 테이블은 인덱싱되지 않은 있습니까? 당신은 우편 번호를 저장하기 위해 NVARCHAR (4000)를 사용 하시겠습니까?

    다른 사람들이 지적했듯이 (예 : 유지 보수로) 쿼리에 사용하려는 각 열을 지정하는 다른 긍정적이있다.

  10. ==============================

    10.당신이 열을 지정 할 때, 당신은 또한 그가 whereever 잘에 걸쳐 Feuerstein에 롤을 만들고, 기둥의 특정 세트에 자신을 묶어 자신이 덜 유연하고 있습니다. 그냥 생각했다.

    당신이 열을 지정 할 때, 당신은 또한 그가 whereever 잘에 걸쳐 Feuerstein에 롤을 만들고, 기둥의 특정 세트에 자신을 묶어 자신이 덜 유연하고 있습니다. 그냥 생각했다.

  11. ==============================

    11.SELECT * 항상 악이 아니다. 제 생각에는, 적어도. 나는 전체 테이블을 반환하는 동적 쿼리, 플러스 몇 가지 계산 된 필드에 자주 사용.

    SELECT * 항상 악이 아니다. 제 생각에는, 적어도. 나는 전체 테이블을 반환하는 동적 쿼리, 플러스 몇 가지 계산 된 필드에 자주 사용.

    예를 들어, 나는하지만 필드 좌표를 포함와, 기하학 필드없이 테이블 "정상적인"테이블에서 지리적 형상을 계산합니다. 나는 PostgreSQL을, 그 공간 확장 PostGIS와를 사용합니다. 그러나 원칙은 다른 많은 경우에 적용됩니다.

    예 :

     place_id |   x   |   y    |   z    |         description          |                            geomfromewkt                            
    ----------+-------+--------+--------+------------------------------+--------------------------------------------------------------------  
            1 | 2.295 | 48.863 | 64.000 | Paris, Place de l'Étoile     | 01010000A0E61000005C8FC2F5285C02405839B4C8766E48400000000000005040  
            2 | 2.945 | 48.858 | 40.000 | Paris, Tour Eiffel           | 01010000A0E61000008FC2F5285C8F0740E7FBA9F1D26D48400000000000004440
            3 | 0.373 | 43.958 | 90.000 | Condom, Cathédrale St-Pierre | 01010000A0E6100000AC1C5A643BDFD73FB4C876BE9FFA45400000000000805640
    (3 lignes)
    

    가장 오른쪽 열이 제대로 포인트를 매핑 할 수있는 GIS 프로그램에서 사용할 수 있습니다.

    나는 VIEW의 정의는 *로, "있는 그대로"유지 될 수 좋겠지 만, hélas 그것은 사실이 아니다 : 이것은 내부적으로 PostgreSQL을 저장하는 방법입니다 :

    SELECT places.place_id, places.x, places.y, places.z, places.description, geomfromewkt (((((( 'SRID = 4326; POINT (':: 텍스트 || places.x) || '': : 지역 정보 geomfromewkt AS 텍스트) || places.y) || '':: 텍스트) || places.z) || ')':: 텍스트);

  12. ==============================

    12.당신은 모든 열을 사용하지만 숫자 인덱스에 의해 행 배열을 해결하더라도 당신이 나중에 다른 행을 추가하는 경우 문제가있을 것입니다.

    당신은 모든 열을 사용하지만 숫자 인덱스에 의해 행 배열을 해결하더라도 당신이 나중에 다른 행을 추가하는 경우 문제가있을 것입니다.

    그래서 기본적으로는 유지 보수의 문제입니다! 당신이 * 선택기를 사용하지 않는 경우 당신은 당신의 쿼리에 대해 걱정할 필요가 없습니다.

  13. ==============================

    13.당신이 필요로하는 열만을 선택하면 작은 메모리에서 데이터 집합을 유지 및 그 응용 프로그램 빠르게 유지합니다.

    당신이 필요로하는 열만을 선택하면 작은 메모리에서 데이터 집합을 유지 및 그 응용 프로그램 빠르게 유지합니다.

    또한, 도구 (예를 들어, 저장 프로 시저) 캐시 쿼리 실행 계획의 많은 너무. (있는 거 선택 뷰 떨어져 당신이 경우 특히 쉬운) 나중에 열을 추가 또는 제거하면 그것이 기대하는 결과를 다시하지 않을 경우,이 도구는 종종 오류가 있습니다.

  14. ==============================

    14.그것은 당신의 코드를보다 모호하고 유지하는 것이 더 어렵게 만든다; 당신은 도메인에 추가되지 않은 데이터를 추가하고, 그것을 당신이 의도 한 적이 없다하는 분명하지 않다 때문이다. (그것은 또한 당신이 알고있는, 또는 걱정하지 않을 수 있음을 의미한다.)

    그것은 당신의 코드를보다 모호하고 유지하는 것이 더 어렵게 만든다; 당신은 도메인에 추가되지 않은 데이터를 추가하고, 그것을 당신이 의도 한 적이 없다하는 분명하지 않다 때문이다. (그것은 또한 당신이 알고있는, 또는 걱정하지 않을 수 있음을 의미한다.)

  15. ==============================

    15.이 기본 테이블의 변경에 코드를 더욱 fragle 보낼 때 음주 "SELECT *"를 사용하지 : 당신이 직접 질문에 대답합니다. 변경이 직접 프로그램의 requirments에 영향을 테이블에 만들어 질 때 귀하의 코드는 중단해야한다.

    이 기본 테이블의 변경에 코드를 더욱 fragle 보낼 때 음주 "SELECT *"를 사용하지 : 당신이 직접 질문에 대답합니다. 변경이 직접 프로그램의 requirments에 영향을 테이블에 만들어 질 때 귀하의 코드는 중단해야한다.

    응용 프로그램이 관계형 액세스를 제공하는 추상화 계층을 활용해야한다.

  16. ==============================

    16.나는 그것을보고 내가 검색하고 필드 알고 좋은이기 때문에 SELECT *를 사용하지 마십시오.

    나는 그것을보고 내가 검색하고 필드 알고 좋은이기 때문에 SELECT *를 사용하지 마십시오.

  17. ==============================

    17.사용하면 테이블 열 변화의 이벤트에서보기를 다시 컴파일 강제되기 때문에 뷰의 내부 '*을 선택'하는 것이 일반적으로 나쁜. 다시 및 재 컴파일 갈 때까지 뷰의 기본 테이블 컬럼을 변경하면 당신은 존재하지 않는 열에 대한 오류가 발생합니다.

    사용하면 테이블 열 변화의 이벤트에서보기를 다시 컴파일 강제되기 때문에 뷰의 내부 '*을 선택'하는 것이 일반적으로 나쁜. 다시 및 재 컴파일 갈 때까지 뷰의 기본 테이블 컬럼을 변경하면 당신은 존재하지 않는 열에 대한 오류가 발생합니다.

  18. ==============================

    18.그것은 당신이 존재하고있는 경우 괜찮아요은 결코 확장하지 도착하기 때문에 (* ... 선택). 그렇지 않으면 일시적으로 선택 문에서도이있는 테이블을 탐색 할 때 정말에만 유용하거나 한 경우 CTE는 위의 정의와 다시 그들 모두를 입력하지 않고 모든 열을 원한다.

    그것은 당신이 존재하고있는 경우 괜찮아요은 결코 확장하지 도착하기 때문에 (* ... 선택). 그렇지 않으면 일시적으로 선택 문에서도이있는 테이블을 탐색 할 때 정말에만 유용하거나 한 경우 CTE는 위의 정의와 다시 그들 모두를 입력하지 않고 모든 열을 원한다.

  19. ==============================

    19.그냥 다른 사람이 언급되지 것을 한 가지를 추가 할 수 있습니다. * 반환 모든 열을 선택, 누군가가 당신이 필요하지 않는 사용자가 마지막으로 등, 모든 사용자 데이터 또는 타임 스탬프 또는 관리자 만이 볼 수 있다는 메모를하지 업데이트 된 사람 등을 볼 수 있도록하려면 나중에 열을 추가 할 수 있습니다

    그냥 다른 사람이 언급되지 것을 한 가지를 추가 할 수 있습니다. * 반환 모든 열을 선택, 누군가가 당신이 필요하지 않는 사용자가 마지막으로 등, 모든 사용자 데이터 또는 타임 스탬프 또는 관리자 만이 볼 수 있다는 메모를하지 업데이트 된 사람 등을 볼 수 있도록하려면 나중에 열을 추가 할 수 있습니다

    열을 추가 할 때 또한, 기존의 코드에 대한 영향을 검토 및 변경 정보는 상기 컬럼에 저장된 내용에 기초하여 필요한 경우 참조하는 것으로 간주되어야한다. 개발자가 아무 것도 깰 것으로 가정하기 때문에 선택 *를 사용하여 그 검토는 종종 ​​생략됩니다. 그리고 사실 아무것도 명시 적으로 중단 것처럼 보일 수 있지만 쿼리는 지금 잘못된 일을 반환 시작할 수 있습니다. 다만 명시 적으로 아무것도 나누기 때문에 쿼리하고 변화가 있어야한다없는 것을 의미하지 않는다.

  20. ==============================

    20.때문에 "SELECT *"당신은 SQL Server의 경우 모든 fields.But이 필요하지 않을 때 메모리를 낭비, 자신의 성취도는 동일합니다.

    때문에 "SELECT *"당신은 SQL Server의 경우 모든 fields.But이 필요하지 않을 때 메모리를 낭비, 자신의 성취도는 동일합니다.

  21. from https://stackoverflow.com/questions/321299/what-is-the-reason-not-to-use-select by cc-by-sa and MIT license