카운트 (집계) SQL 쿼리를 수행 할 때이 3 개의 데이터베이스 시스템에서 실행 시간을 단축 할 수있는 것은 무엇입니까? 나는 많은 것들이 속도를 높일 수 있다고 확신하지만 (하나는 하드웨어), 나는 초보자 DBA 일 뿐이므로 여기에 몇 가지 대답을 얻을 것이라고 확신합니다. 약 1 억 5 천 5 백만 행을 SQL Server 데이터베이스로 마이그레이션했으며이 쿼리는 계속 진행되고 있습니다. 그러나 소스 Netezza 데이터베이스에서는 몇 초가 걸립니다.
예를 들면 다음과 같습니다.
네 테짜 6 :
SELECT COUNT(*) FROM DATABASENAME..MYTABLE
Oracle 11g :
SELECT COUNT(*) FROM MYTABLE
SQL Server 2012 :
SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]
답변
Netezza는 큰 테이블 스캔에서 탁월하도록 설계된 어플라이언스이므로 해당 시스템에서 빠른 결과를 얻을 수 있습니다.
SQL Server의 경우 sys.dm_db_partition_stats DMV에서 쿼리하여 행 수를 크게 높일 수 있습니다.
SELECT s.name AS [Schema], o.name AS [Table], SUM(p.row_count) AS [RowCount]
FROM sys.dm_db_partition_stats p JOIN sys.objects o
ON p.object_id = o.object_id JOIN sys.schemas s
ON o.schema_id = s.schema_id
WHERE p.index_id < 2
AND o.object_id = object_id('MyTable')
GROUP BY o.name, s.name;
트랜잭션이 많은 환경에서이 DMV는 100 % 정확한 것은 아닙니다. 그러나 귀하의 질문에 따르면, 마이그레이션 후 각 테이블을 확인하기 위해 행 수를 수행하는 것처럼 들리 므로이 쿼리가 효과적입니다.
답변
다음 COUNT_BIG
은 인덱싱 된 뷰 내부 를 사용하는 SQL Server 솔루션입니다 . 이렇게하면 큰 테이블 또는 인덱스 스캔의 오버 헤드가없고 후자에 필요한 스토리지가 없어도 트랜잭션에 일관성이있는 수를 얻을 수 있습니다.
CREATE TABLE [dbo].[MyTable](id int);
GO
CREATE VIEW [dbo].[MyTableRowCount]
WITH SCHEMABINDING
AS
SELECT
COUNT_BIG(*) AS TableRowCount
FROM [dbo].[MyTable];
GO
CREATE UNIQUE CLUSTERED INDEX IX_MyTableRowCount
ON [dbo].[MyTableRowCount](TableRowCount);
GO
SELECT
TableRowCount
FROM [dbo].[MyTableRowCount] WITH(NOEXPAND);
이를 위해서는 단일 초기 스캔이 필요하며 (이를 피할 수는 없음) 증분 테이블 데이터 조작에 약간의 오버 헤드가 추가됩니다. 많은 작은 작업과 달리 많은 데이터로 큰 작업을 수행하는 경우 변경에 대한 오버 헤드는 무시할 만하다고 생각합니다.
답변
Oracle에서는 NOT NULL 열의 이진 트리 인덱스를 사용하여 COUNT (*)에 응답 할 수 있습니다. 인덱스는 일반적으로 기본 테이블보다 작기 때문에 대부분의 경우 FULL TABLE SCAN보다 빠릅니다.
그러나 일반 이진 트리 인덱스는 여전히 157 Mrows입니다. 테이블이 동시에 업데이트되지 않으면 (즉, 일괄로드 프로세스 만 해당) 비트 맵 인덱스를 대신 사용할 수 있습니다.
가장 작은 비트 맵 인덱스는 다음과 같습니다.
CREATE BITMAP INDEX ix ON your_table(NULL);
비트 맵 인덱스는 널 항목을 고려합니다. 결과 인덱스는 일반 이진 트리 인덱스 또는 기본 테이블에 비해 작습니다 (백만 행당 20-30 8k 블록).
결과 계획에는 다음 작업이 표시되어야합니다.
----------------------------------------------
| Id | Operation | Name |
----------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | BITMAP CONVERSION COUNT | |
| 3 | BITMAP INDEX FAST FULL SCAN| IX |
----------------------------------------------
테이블이 동시에 업데이트되면 고유 한 값을 가진 비트 맵 인덱스가 경합 지점이되어 사용해서는 안됩니다.
답변
Oracle에서 단순 카운트 쿼리는 종종 전체 테이블 대신 인덱스를 스캔하여 실행됩니다. 인덱스는 비트 맵 인덱스이거나 NOT NULL 제약 조건이있는 열에 정의되어야합니다. 전체 테이블 스캔이 필요한보다 복잡한 쿼리의 경우 병렬 쿼리를 사용할 수 있습니다.
병렬 쿼리를 사용하려면 (Enterprise Edition 필요) 최적화 힌트를 사용할 수 있습니다.
select /*+ PARALLEL(mytable, 12) */ count(*) from mytable;
또는 테이블의 모든 쿼리에 대해 병렬 쿼리를 활성화하십시오.
alter table mytable parallel 12;