[sql] 개수 (*) 및 개수 (1)-SQL Server

사람들 중 일부를 Count(1)과도하게 사용 하고 Count(*)성능에 눈에 띄는 차이가 있는지 또는 과거의 일에서 제기 된 레거시 습관인지 궁금하십니까?

특정 데이터베이스는 SQL Server 2005입니다.



답변

다른 점이 없다.

이유:

온라인 서적에COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

“1”은 널이 아닌 표현식입니다. 따라서와 동일합니다 COUNT(*). 옵티마이 저는이를 사소한 것으로 인식합니다.

와 동일 EXISTS (SELECT * ...또는EXISTS (SELECT 1 ...

예:

SELECT COUNT(1) FROM dbo.tab800krows
SELECT COUNT(1),FKID FROM dbo.tab800krows GROUP BY FKID

SELECT COUNT(*) FROM dbo.tab800krows
SELECT COUNT(*),FKID FROM dbo.tab800krows GROUP BY FKID

같은 IO, 같은 계획, 작품

2011 년 8 월 편집

DBA.SE와 비슷한 질문입니다 .

2011 년 12 월 수정

COUNT(*)ANSI-92에 구체적으로 언급되어 있습니다 ( ” Scalar expressions 125“)

케이스:

a) COUNT (*)가 지정되면 결과는 T의 카디널리티입니다.

즉, ANSI 표준은이를 의미하는 출혈로 인식합니다. 이 미신 때문에COUNT(1) RDBMS 공급 업체가 최적화했습니다 . 그렇지 않으면 ANSI에 따라 평가됩니다

b) 그렇지 않으면 TX가 <value expression>을 T의 각 행에 적용하고 널값을 제거한 결과 인 단일 열 테이블이되게하십시오. 하나 이상의 널값이 제거되면 완료 조건이 발생합니다. warning-


답변

SQL Server에서 이러한 명령문은 동일한 계획을 산출합니다.

대중의 의견과는 달리, 오라클에서도 마찬가지입니다.

SYS_GUID() 오라클에서는 계산 집약적 인 기능입니다.

내 테스트 데이터베이스에서 행 t_even이있는 테이블입니다.1,000,000

이 쿼리 :

SELECT  COUNT(SYS_GUID())
FROM    t_even

48함수가 SYS_GUID()반환 된 각 값을 평가하여이 값 이 아닌지 확인 해야하기 때문에 몇 초 동안 실행됩니다 NULL.

그러나이 쿼리는 다음과 같습니다.

SELECT  COUNT(*)
FROM    (
        SELECT  SYS_GUID()
        FROM    t_even
        )

2평가조차하지 않기 때문에 몇 초 동안 실행됩니다 (에 대한 논쟁 SYS_GUID()에도 불구하고 )*COUNT(*)


답변

분명히, COUNT(*)그리고 COUNT(1)것입니다 항상 같은 결과를 반환합니다. 따라서 하나가 다른 것보다 느리면 효과적으로 최적화 버그로 인한 것입니다. 두 형식 모두 쿼리에서 매우 자주 사용되므로 DBMS가 이러한 버그를 수정하지 않은 상태로 유지하는 것은 의미가 없습니다. 따라서 모든 주요 SQL DBMS에서 두 양식의 성능이 동일 할 것입니다.


답변

SQL Server 팀에서 일하고 있으며이 스레드에서 몇 가지 요점을 명확하게 설명 할 수 있습니다 (이전에 본 적이 없으므로 엔지니어링 팀이 이전에 수행하지 않은 것이 유감입니다).

첫째, 사이에 의미 차이가없는 select count(1) from table비교는 select count(*) from table. 그들은 모든 경우에 동일한 결과를 반환합니다 (그렇지 않으면 버그입니다). 다른 답변에서 언급했듯이 select count(column) from table의미 적으로 다르며 항상 같은 결과를 반환하지는 않습니다 count(*).

둘째, 성능과 관련하여 SQL Server (및 SQL Azure)에서 중요한 두 가지 측면, 즉 컴파일 타임 작업과 실행 타임 작업이 있습니다. 컴파일 시간 작업은 현재 구현에서 사소한 추가 작업입니다. 일부 경우에 *를 모든 열로 확장 한 후 일부 내부 조작이 바인딩 및 최적화에서 작동하는 방식으로 인해 출력이 1 열로 다시 축소됩니다. 나는 그것이 측정 가능한 테스트에 나타날 것이라고 의심하고, 커버 아래에서 발생하는 다른 모든 것들 (예 : 자동 통계, xevent 세션, 쿼리 저장소 오버 헤드, 트리거 등)에서 잡음이 손실 될 수 있습니다. 수천 개의 추가 CPU 명령어 일 수 있습니다. 그래서, count (1)은 컴파일하는 동안 약간의 작업을 덜 수행합니다 (일반적으로 한 번 발생하며 계획은 여러 후속 실행에서 캐시 됨). 실행 시간 동안 계획이 동일하다고 가정하면 측정 가능한 차이가 없어야합니다. (이전 예제 중 하나는 차이점을 보여줍니다. 계획이 동일한 경우 시스템의 다른 요인으로 인한 것일 수 있습니다).

계획이 어떻게 다를 수 있는지에 대해. 이러한 상황은 거의 발생하지 않지만 현재 옵티마이 저의 아키텍처에서 가능할 수 있습니다. SQL Server의 옵티마이 저는 검색 프로그램으로 작동합니다 (컴퓨터 프로그램은 쿼리의 다른 부분에 대한 다양한 대안을 통해 체스 검색을 수행하고 합리적인 시간에 가장 저렴한 계획을 찾기 위해 대안을 계산합니다). 이 검색에는 쿼리 컴파일을 적절한 시간 내에 완료하기 위해 작동하는 방식에 몇 가지 제한이 있습니다. 가장 사소한 쿼리 이외의 쿼리에는 검색 단계가 있으며 쿼리가 잠재적으로 쿼리를 실행하는 데 비용이 얼마나 많이 드는지에 따라 쿼리 트랜치를 처리합니다. 3 가지 주요 검색 단계가 있으며 각 단계는 이전 솔루션보다 저렴한 요금제를 찾으려고보다 공격적인 (비싼) 휴리스틱을 실행할 수 있습니다. 궁극적으로 각 단계의 끝에는 지금까지 찾은 계획을 반환해야하는지 또는 계속 검색해야하는지 결정하는 결정 프로세스가 있습니다. 이 프로세스는 지금까지 걸린 총 계획 시간과 지금까지 찾은 최상의 계획의 예상 비용을 사용합니다. 따라서 CPU 속도가 다른 여러 시스템에서 계획이있는 이전 단계에서 다음 검색 단계로 진행하여 이전 단계에서 시간이 초과되어 다른 계획을 얻을 수 있습니다 (드물지만). 마지막 단계의 시간 초과 및 시스템의 모든 메모리를 소비하는 매우 고가의 쿼리에서 잠재적으로 메모리 부족과 관련된 몇 가지 유사한 시나리오도 있습니다 (일반적으로 64 비트의 문제는 아니지만 더 큰 관심 사임) 32 비트 서버로 돌아 가기). 궁극적으로 다른 계획을 세우면 런타임시 성능이 달라집니다. 나는

인터넷 :이 두 가지 중 어느 것도 원하는 형태로 사용하지 마십시오. (이 주제 이상으로 SQL 성능에 영향을 미치는 훨씬 더 큰 요소가 솔직히 있습니다).

이게 도움이 되길 바란다. 옵티마이 저의 작동 방식에 대한 책 장을 작성했지만 여기에 게시하는 것이 적절한 지 모르겠습니다. 따라서 영국의 SQLBits에서 최적화 프로그램이 높은 수준으로 작동하는 방식에 대해 이야기 한 링크에 게시한다고 게시하면 원하는 경우 검색의 다른 주요 단계를 좀 더 자세히 볼 수 있습니다 그것에 대해 배울 수 있습니다. 비디오 링크는 다음과 같습니다. https://sqlbits.com/Sessions/Event6/inside_the_sql_server_query_optimizer


답변

SQL-92 Standard에서 COUNT(*)구체적으로 “테이블 표현식의 카디널리티”(기본 테이블,`VIEW, 파생 테이블, CTE 등일 수 있음)를 의미합니다.

아이디어가 COUNT(*)파싱하기 쉽다 는 생각이 들었습니다. 다른 표현을 사용하는 것은 임의의 열을 참조하지 않도록 할 필요 파서 ( COUNT('a')여기서 a리터럴 및 COUNT(a)a이다 열 다른 결과를 얻을 수있다).

같은 맥락에서, COUNT(*)하나 이상의 벤더의 SQL 오퍼링을 작업 할 때 유용한 기술인 SQL 표준에 익숙한 인간 코더가 쉽게 선택할 수 있습니다.

또한 특별한 경우 SELECT COUNT(*) FROM MyPersistedTable; DBMS가 테이블의 카디널리티에 대한 통계를 보유 할 가능성이 있다고 생각합니다.

때문에 따라서, COUNT(1)그리고 COUNT(*)의미 동일, 내가 사용 COUNT(*).


답변

COUNT(*)그리고 COUNT(1)그 결과 성능의 경우와 동일하다.


답변

옵티마이 저가 이상한 경우를 제외하고는 실질적인 차이가 없는지 확인해야합니다.

다른 것과 마찬가지로, 실제로 말할 수있는 유일한 방법은 특정 사례를 측정하는 것입니다.

즉, 나는 항상 사용했습니다 COUNT(*).