카테고리 보관물: Sql

sql

SQL 카운트 쿼리 속도를 높일 수있는 것은 무엇입니까? 일 뿐이므로

카운트 (집계) 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;


답변