Co może przyspieszyć zapytanie licznika SQL?

9

Co może przyśpieszyć liczenie (agregowanie) zapytania SQL w tych 3 systemach baz danych? Jestem pewien, że wiele rzeczy może to przyspieszyć (sprzęt dla jednego), ale jestem tylko początkującym DBA, więc jestem pewien, że otrzymam kilka odpowiedzi tutaj. Przeprowadziłem migrację około 157 milionów wierszy do bazy danych SQL Server, a to zapytanie trwa wiecznie. Ale w mojej źródłowej bazie danych Netezza zajmuje to kilka sekund.

Na przykład:

Netezza 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL Server 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]
MacGyver
źródło
1
Czy musisz to zrobić tylko raz, czy wielokrotnie?
Jon Seigel
@JonSeigel wykonujemy obciążenia przyrostowe i każdego dnia porównujemy rekordy między systemami baz danych, aby upewnić się, że liczby się sumują. Tak wielokrotnie.
MacGyver

Odpowiedzi:

10

Netezza to urządzenie zaprojektowane z myślą o doskonałych wynikach podczas skanowania dużych tabel, dlatego otrzymujesz tak szybkie wyniki w tym systemie.

W przypadku serwera SQL Server można znacznie przyspieszyć liczenie wierszy, wysyłając zapytanie z 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;

W środowisku o wysokich transakcjach nie ma gwarancji, że ten DMV będzie w 100% dokładny. Ale z twojego pytania wynika, że ​​po prostu wykonujesz liczenie wierszy, aby zweryfikować każdą tabelę po migracji, więc to zapytanie powinno działać dla Ciebie.

Patrick Keisler
źródło
4
@Phil dlaczego? Jeśli przejrzysz tabele i wykonasz z nich kosztowny WYBÓR LICZBY (*) - jak dokładny jest pierwszy wynik po dotarciu do ostatniego stołu?
Aaron Bertrand
1
Dla jasności Phil powiedział: „Korzystanie ze słownika danych, który nie zapewnia 100% dokładnych wyników, jest złą radą. Moim zdaniem odpowiedź powinna zostać zredagowana w celu usunięcia sugestii lub usunięta - pamiętaj, że ludzie szukają takich odpowiedzi w Google i ślepo wytnij i wklej ... ”Zgadzam się, że wyłączenie odpowiedzialności jest ważne (i są rzekomo pewne przypadki skrajne, w których metadane nie zwracają rozsądnych wyników), nie zgadzam się, że korzystanie z widoków metadanych w ogóle jest złą radą.
Aaron Bertrand
5

Oto rozwiązanie programu SQL Server, które wykorzystuje COUNT_BIGwidok indeksowany. Dzięki temu uzyskasz spójną transakcyjnie liczbę bez narzutów związanych z dużymi skanami tabel lub indeksów i bez potrzeby przechowywania pamięci wymaganej dla tych ostatnich:

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

Będzie to wymagało jednego początkowego skanowania (bez uciekania się od tego) i doda trochę narzutu do przyrostowych manipulacji danymi w tabeli. Jeśli wykonujesz duże operacje z dużą ilością danych (w przeciwieństwie do wielu małych operacji), myślę, że narzut na zmiany powinien być znikomy.

Jon Seigel
źródło
@SQLKiwi: Dlaczego odczyty są blokowane przed 2012 r.? Błąd programu SQL Server?
Jon Seigel
@JonSeigel - Moje 0,05 $: Normalne indeksy klastrowe na normalnej tabeli utworzonej offline stosuje blokadę Sch-M na stole. W widoku, oczywiście, nie jest to potrzebne, ale oznacza to zmianę operacji Utwórz indeks, aby utworzyć specjalny przypadek dla widoku indeksowanego - co zostało zrobione dla SQL2012. Oczywiście IMHO.
Fabricio Araujo
3

W Oracle można użyć indeksu drzewa binarnego w kolumnie NOT NULL, aby odpowiedzieć na COUNT (*). W większości przypadków będzie on szybszy niż SKANOWANIE PEŁNEJ TABELI, ponieważ indeksy są zwykle mniejsze niż ich tabela bazowa.

Jednak regularny indeks drzewa binarnego nadal będzie ogromny z 157 Mrowami. Jeśli twoja tabela nie jest aktualizowana jednocześnie (tzn. Tylko proces ładowania wsadowego), możesz zamiast tego użyć indeksu bitmap.

Najmniejszy indeks bitmapowy wyglądałby mniej więcej tak:

CREATE BITMAP INDEX ix ON your_table(NULL);

Wpisy zerowe są uwzględniane przez indeks bitmapowy. Wynikowy indeks będzie niewielki (20-30 8 tys. Bloków na milion wierszy) w porównaniu do zwykłego indeksu drzewa binarnego lub tabeli podstawowej.

Wynikowy plan powinien pokazywać następujące operacje:

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

Jeśli twoja tabela jest aktualizowana jednocześnie, indeks bitmapowy z unikalną wartością będzie punktem spornym i nie powinien być używany.

Vincent Malgrat
źródło
3

W Oracle proste zapytanie zliczające jest często wykonywane przez skanowanie indeksu zamiast całej tabeli. Indeks musi być indeksem bitmapowym lub być zdefiniowany w kolumnie z ograniczeniem NOT NULL. W przypadku bardziej złożonych zapytań wymagających pełnego skanowania tabeli można użyć zapytania równoległego.

Aby włączyć kwerendę równoległą (wymagana wersja Enterprise), możesz użyć wskazówki optymalizatora:

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

Lub włącz równoległe zapytanie dla wszystkich zapytań w tabeli:

alter table mytable parallel 12;
sjk
źródło