[SQL] COUNT (*) 대 수 (1) 대 수 (PK) : 더 나은 무엇입니까? [복제]
SQLCOUNT (*) 대 수 (1) 대 수 (PK) : 더 나은 무엇입니까? [복제]
나는 종종이 세 가지 변종을 찾을 수 있습니다 :
SELECT COUNT(*) FROM Foo;
SELECT COUNT(1) FROM Foo;
SELECT COUNT(PrimaryKey) FROM Foo;
최대한 멀리 볼 수, 그들은 모두 같은 일을하고, 내 코드베이스의 3을 사용하여 자신을 찾을 수 있습니다. 그러나, 나는 같은 일을 여러 가지 방법을 좋아하지 않아요. 어느 하나에 나는 충실해야한다고? 어떤 두 개의 다른 사람보다 그들 중 하나가 더 나은가요?
해결법
-
==============================
1.일관되게과 중 COUNT (필드) 또는 COUNT (*), 스틱을 사용하여 데이터베이스가 허용하는 경우 COUNT (tableHere) 또는 COUNT (tableHere. *) 사용하는 것이.
일관되게과 중 COUNT (필드) 또는 COUNT (*), 스틱을 사용하여 데이터베이스가 허용하는 경우 COUNT (tableHere) 또는 COUNT (tableHere. *) 사용하는 것이.
즉, 아무것도 COUNT (1)를 사용하지 않습니다. 그것은 거의 당신이 원하는 것을하지 않습니다 원 트릭 포니,, 그리고 그 드문 경우에 수에 해당합니다 (*)
필요, 결합도에 대한 사용을 모든 카운트하는 모든 쿼리에 대한 사용 * *
SELECT boss.boss_id, COUNT(subordinate.*) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
하위 테이블이 부모 테이블에서 아무것도 일치하지 않는 경우에도 그 일을 반환하지만, LEFT 조인에 대한 COUNT (*)를 사용하지 않는
SELECT boss.boss_id, COUNT(*) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
COUNT에 *를 사용하는 경우, 그것은 그 *이 느린 말, 테이블에서 전체 행을 반입하는 조언들에 속지 마십시오. SELECT 수 (*)를 선택 함 * * *은 그들이 그들이 단지 일반적인 토큰을 공유하도록, 즉 완전히 다른 건, 서로 전혀 관계가 없다.
그것의 테이블 이름과 동일 필드 이름을 허용하지 않을 경우 사실, RDBMS 언어 디자이너는 COUNT (tableNameHere) COUNT (*)와 같은 의미를 줄 수 있습니다. 예:
계산 행의 경우 우리는 이것을 할 수 :
SELECT COUNT(emp) FROM emp
그리고 그들은 그것을 간단하게 만들 수 :
SELECT COUNT() FROM emp
LEFT 조인을 위해, 우리는 이것을 할 수 :
SELECT boss.boss_id, COUNT(subordinate) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
그러나 그들은 그것의 테이블 이름과 같은 이름의 필드 이름을 지정 SQL 표준 허용 이후 그 (COUNT (tableNameHere))를 수행 할 수 없습니다
CREATE TABLE fruit -- ORM-friendly name ( fruit_id int NOT NULL, fruit varchar(50), /* same name as table name, and let's say, someone forgot to put NOT NULL */ shape varchar(50) NOT NULL, color varchar(50) NOT NULL )
또한, 그것의 이름은 테이블 이름과 일치하는 경우 필드 널 (NULL)을 만들 수있는 좋은 방법이 아닙니다. 당신이 값 '바나나'을 말해봐 '애플', NULL, 과일 필드에서 '배'. 이것은 모든 행을 계산하지 않습니다 만 4, 3을 얻을하지 않습니다
SELECT count(fruit) FROM fruit
일부 RDBMS 원칙의 종류를 할 수 있지만 어떤 하위 필드 길이가 한 예를 아래에 두 테이블 중 어느이없는 경우이 (PostgreSQL을에서 작동합니다 (테이블의 행을 카운트를 들어, COUNT의 매개 변수로 테이블 이름을 허용) 아니오) 필드 이름과 테이블 이름 사이의 충돌 이름 :
SELECT boss.boss_id, COUNT(subordinate) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
이 (널 (NULL)이 될 수 있음) 분야를 계산합니다 우리가, 표에없는 테이블 행을 하위 필드를 추가합니다하지만 그 이후 혼란의 원인이 될 수 있습니다.
그래서 안전을 위해, 사용 :
SELECT boss.boss_id, COUNT(subordinate.*) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
특히 (1) COUNT하기 위해, 그것은 하나 개의 테이블 쿼리에서 잘 작동 한 트릭 포니입니다 :
SELECT COUNT(1) FROM tbl
그러나 사용할 때 그 트릭은 의미가없는 멀티 테이블 쿼리에없는 작업이 혼동되는 것, 특히 당신이 쓸 수 없습니다, 조인
-- count the subordinates that belongs to boss SELECT boss.boss_id, COUNT(subordinate.1) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
그래서 여기 COUNT (1)의 의미는 무엇인가?
SELECT boss.boss_id, COUNT(1) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
그것은이다 ...?
-- counting all the subordinates only SELECT boss.boss_id, COUNT(subordinate.boss_id) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
아니면 이거...?
-- or is that COUNT(1) will also count 1 for boss regardless if boss has a subordinate SELECT boss.boss_id, COUNT(*) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
신중하게 생각하면 그 COUNT (1)에 관계없이 가입의 종류, COUNT (*)와 동일한 추론 할 수있다. LEFT이 결과를 조인을 위해, 우리는 같은 일에 COUNT (1)를 성형 할 수 없습니다. (하위 *) COUNT (subordinate.boss_id), COUNT
그래서 바로 다음 중 하나를 사용합니다 :
-- count the subordinates that belongs to boss SELECT boss.boss_id, COUNT(subordinate.boss_id) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
PostgreSQL을에 작품, 당신이 세트의 중요도를 계산 할 것이 분명
-- count the subordinates that belongs to boss SELECT boss.boss_id, COUNT(subordinate.*) FROM boss LEFT JOIN subordinate on subordinate.boss_id = boss.boss_id GROUP BY boss.id
또 다른 방법은 매우 영어-(같은 단지의 테이블 이름과 동일한 이름을 가진 열을하지 않는다) 세트의 중요도를 계산하는 방법 : http://www.sqlfiddle.com/#!1/98515/7
select boss.boss_name, count(subordinate) from boss left join subordinate on subordinate.boss_code = boss.boss_code group by boss.boss_name
당신은이 작업을 수행 할 수 없습니다 http://www.sqlfiddle.com/#!1/98515/8
select boss.boss_name, count(subordinate.1) from boss left join subordinate on subordinate.boss_code = boss.boss_code group by boss.boss_name
당신은이 작업을 수행 할 수 있지만,이 잘못된 결과를 생성 : http://www.sqlfiddle.com/#!1/98515/9
select boss.boss_name, count(1) from boss left join subordinate on subordinate.boss_code = boss.boss_code group by boss.boss_name
-
==============================
2.그 중 두 항상 같은 대답을 생산 :
그 중 두 항상 같은 대답을 생산 :
약동학 가정하면에는 널이어서, 값으로 허용되는 기본 키이며
PK가 NOT NULL로 제한되어 있지 않은 경우, 그것은 다른 대답을 생성합니다
일반적으로, 나는 COUNT (*)를 쓰기; 그것은 SQL의 원래 권장 표기법입니다. 절로 존재와 존재하는 그 때문에 원래 표기법을 추천했다 마찬가지로, 나는 일반적으로 (... SELECT * FROM) 물품. 대안 아무런 혜택이 없을 것; 옵티마이 저는 더 애매한 표기법을 통해 볼 수 있습니다.
-
==============================
3.이것은 당신이 사용하고있는 데이터베이스의 종류뿐만 아니라 경우에 따라 테이블의 유형에 따라 달라집니다.
이것은 당신이 사용하고있는 데이터베이스의 종류뿐만 아니라 경우에 따라 테이블의 유형에 따라 달라집니다.
MySQL을 사용 예를 들어, (*)는 이노 아래 MyISAM 테이블하지만 느린에서 빠른 것입니다 계산합니다. 이노에서 당신은 수 (1)을 사용하거나 (PK) 계산한다.
-
==============================
4.질문과 전에 대답 ...
질문과 전에 대답 ...
온라인 도서는 "COUNT ({* [| | DISTINCT] 식 [전체]})"라고
이 COUNT (*)와 동일한 그래서 "1"비 - 널 식이다. 옵티마이 사소한로 인식 때문에 같은 계획을 제공합니다. PK가 고유 및 비 - 널 (SQL 서버 적어도) COUNT 그렇다 (PK) = COUNT (*)
이것은 ... EXISTS (SELECT * 유사한 신화 또는 (1을 선택 EXISTS ...
그리고 ANSI 92 사양, 섹션 6.5, 일반 규칙, 사례 1 참조
a) If COUNT(*) is specified, then the result is the cardinality of T. b) Otherwise, let TX be the single-column table that is the result of applying the <value expression> to each row of T and eliminating null values. If one or more null values are eliminated, then a completion condition is raised: warning- null value eliminated in set function.
-
==============================
5.오라클에 적어도 그들은 모두 동일합니다 http://www.oracledba.co.uk/tips/count_speed.htm
오라클에 적어도 그들은 모두 동일합니다 http://www.oracledba.co.uk/tips/count_speed.htm
-
==============================
6.나는 또 다른 하나의 DBMS의 성능 특성 변화를 느낍니다. 그것은 그들이 그것을 구현하기 위해 선택하는 방법에 대한 전부입니다. 내가 오라클에 광범위하게 일했기 때문에, 그 관점에서 말할 것이다.
나는 또 다른 하나의 DBMS의 성능 특성 변화를 느낍니다. 그것은 그들이 그것을 구현하기 위해 선택하는 방법에 대한 전부입니다. 내가 오라클에 광범위하게 일했기 때문에, 그 관점에서 말할 것이다.
COUNT는 (*) - 로우 null가 아닌 경우 카운트 함수에 전달하기 전에 결과 집합으로 전체 행을 가져오고, 함수는 1을 계산한다 집계
COUNT (1) - 어떤 행을 인출하지 않음은, 대신 카운트는 경우 WHERE 일치 테이블의 각 행에 대해 1의 일정한 값이라고합니다.
COUNT (PK) - 오라클의 PK 색인된다. 이것은 오라클은 인덱스를 읽을 수 있습니다 의미합니다. 일반적으로 인덱스 B의 + 트리에서 한 행은 실제 행보다 몇 배 작다. 그래서 디스크 IOPS 속도를 고려, 오라클은 전체 행에 비해 하나의 블록 전송과 많은 시간을 지수에서 더 많은 행을 가져올 수 있습니다. 쿼리의 높은 처리량이 리드.
이로부터 첫 번째 카운트가 느린이며, 마지막 카운트가 오라클에서 가장 빠른 볼 수 있습니다.
from https://stackoverflow.com/questions/2710621/count-vs-count1-vs-countpk-which-is-better by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] MySQL의 테이블 열 이름을 얻기? (0) | 2020.03.16 |
---|---|
[SQL] 어떻게 무작위 SQL에서 행을 선택하려면? (0) | 2020.03.16 |
[SQL] SQL 쿼리와 가까운 위도 / 경도 찾기 (0) | 2020.03.16 |
[SQL] 왜 IN 조건은 SQL에서 "="보다 느린 것입니까? (0) | 2020.03.16 |
[SQL] 어떻게 두 테이블에 MySQL에 합류? (0) | 2020.03.16 |