O que pode acelerar uma consulta de contagem SQL?

9

Ao fazer uma consulta SQL de contagem (agregada), o que pode acelerar o tempo de execução nesses 3 sistemas de banco de dados? Tenho certeza de que muitas coisas podem acelerar (hardware para um), mas sou apenas um DBA iniciante, por isso tenho certeza de que vou receber algumas respostas aqui. Migrei cerca de 157 milhões de linhas para um banco de dados do SQL Server, e essa consulta está demorando uma eternidade. Mas no meu banco de dados Netezza de origem, leva segundos.

Por exemplo:

Netezza 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL Server 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]
MacGyver
fonte
11
Você precisa fazer isso apenas uma vez ou repetidamente?
21412 Jon Seigel
@JonSeigel, estamos fazendo cargas incrementais e comparando registros entre sistemas de banco de dados todos os dias para garantir que as contagens aumentem. Tão repetidamente.
MacGyver

Respostas:

10

O Netezza é um dispositivo projetado para se destacar em varreduras de tabelas grandes; é por isso que você está obtendo resultados tão rápidos nesse sistema.

Para o SQL Server, você pode acelerar bastante a contagem de linhas consultando a DMV sys.dm_db_partition_stats.

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;

Em um ambiente de alta transação, não é garantido que esse DMV seja 100% preciso. Mas, com a sua pergunta, parece que você está apenas fazendo contagens de linhas para verificar cada tabela após a migração, portanto, essa consulta deve funcionar para você.

Patrick Keisler
fonte
4
@Phil why? Se você percorrer as tabelas e executar uma SELECIONAR CONTAGEM (*) dispendiosa de cada uma delas, qual é a precisão do primeiro resultado depois de chegar à última tabela?
Aaron Bertrand
11
Para maior clareza, Phil havia dito: "Usar o dicionário de dados, que não fornece resultados 100% precisos, é um mau conselho. Na minha opinião, a resposta deve ser editada para remover a sugestão ou excluída - lembre-se de procurar no Google as pessoas por essas respostas e cegamente recortar e colar ... "Concordo que o aviso de isenção de responsabilidade é importante (e há casos alegados em que os metadados não retornam resultados razoáveis), discordo que o uso das visualizações de metadados em geral é um mau conselho.
Aaron Bertrand
5

Aqui está uma solução do SQL Server que usa COUNT_BIGdentro de uma exibição indexada. Isso proporcionará uma contagem consistente de transações, sem a sobrecarga de grandes varreduras de tabela ou índice e sem a necessidade do armazenamento necessário para a última:

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);

Isso exigirá uma única varredura inicial (sem fugir disso) e adicionará um pouco de sobrecarga às manipulações incrementais de dados da tabela. Se você estiver realizando grandes operações com muitos dados (em oposição a muitas pequenas operações), acho que a sobrecarga nas alterações deve ser insignificante.

Jon Seigel
fonte
@SQLKiwi: Como as leituras são bloqueadas antes de 2012? Bug do SQL Server?
22612 Jon Seigel
@ JonSeigel - Meus US $ 0,05: índices agrupados normais na tabela normal criados offline aplicam um bloqueio Sch-M na tabela. Em uma exibição, é claro que não é necessário, mas isso significa uma alteração na operação Criar Índice para criar um caso especial para a exibição indexada - o que foi feito para o SQL2012. IMHO, é claro.
Fabricio Araujo
3

No Oracle, um índice de árvore binária em uma coluna NOT NULL pode ser usado para responder a COUNT (*). Na maioria dos casos, será mais rápido que uma VERIFICAÇÃO DE TABELA COMPLETA, porque os índices geralmente são menores que sua tabela base.

No entanto, um índice de árvore binária regular ainda será enorme com 157 Mrows. Se sua tabela não for atualizada simultaneamente (ou seja, apenas processo de carregamento em lote), convém usar um índice de bitmap.

O menor índice de bitmap seria algo como isto:

CREATE BITMAP INDEX ix ON your_table(NULL);

Entradas nulas são levadas em conta por um índice de bitmap. O índice resultante será pequeno (20 a 30 blocos de 8k por milhão de linhas) em comparação com um índice comum da árvore binária ou com a tabela base.

O plano resultante deve mostrar as seguintes operações:

----------------------------------------------
| Id  | Operation                     | Name | 
----------------------------------------------
|   0 | SELECT STATEMENT              |      |
|   1 |  SORT AGGREGATE               |      |
|   2 |   BITMAP CONVERSION COUNT     |      |
|   3 |    BITMAP INDEX FAST FULL SCAN| IX   |
----------------------------------------------

Se sua tabela for atualizada simultaneamente, um índice de bitmap com um valor exclusivo será um ponto de discórdia e não deverá ser usado.

Vincent Malgrat
fonte
3

No Oracle, a consulta simples de contagem é frequentemente executada varrendo um índice em vez de uma tabela inteira. O índice deve ser um índice de bitmap ou definido em uma coluna com restrição NOT NULL. Para consultas mais complexas que exigem verificação completa da tabela, você pode usar a consulta paralela.

Para habilitar a consulta paralela (é necessário o Enterprise Edition), você pode usar a dica do otimizador:

select /*+ PARALLEL(mytable, 12) */ count(*) from mytable;

Ou ative a consulta paralela para todas as consultas na tabela:

alter table mytable parallel 12;
sjk
fonte