Was kann eine SQL-Zählabfrage beschleunigen?


9

Was kann bei einer SQL-Abfrage (aggregiert) die Ausführungszeit in diesen drei Datenbanksystemen beschleunigen? Ich bin mir sicher, dass viele Dinge es beschleunigen könnten (Hardware für einen), aber ich bin nur ein unerfahrener DBA, also bin ich sicher, dass ich hier ein paar Antworten bekommen werde. Ich habe ungefähr 157 Millionen Zeilen in eine SQL Server-Datenbank migriert, und diese Abfrage dauert ewig. In meiner Netezza-Quelldatenbank dauert es jedoch Sekunden.

Zum Beispiel:

Netezza 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL Server 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]


1
Müssen Sie dies nur einmal oder wiederholt tun?
Jon Seigel

@ JonSeigel Wir führen inkrementelle Ladevorgänge durch und vergleichen jeden Tag Datensätze zwischen Datenbanksystemen, um sicherzustellen, dass sich die Anzahl summiert. Also immer wieder.
MacGyver

Antworten:


10

Netezza ist eine Appliance, die sich hervorragend für große Tischscans eignet. Deshalb erzielen Sie mit diesem System so schnelle Ergebnisse.

Für Ihren SQL Server können Sie die Zeilenanzahl erheblich beschleunigen, indem Sie die DMV sys.dm_db_partition_stats abfragen.

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;

In einer Umgebung mit hohen Transaktionen ist nicht garantiert, dass diese DMV 100% genau ist. Aus Ihrer Frage geht jedoch hervor, dass Sie nur Zeilenzählungen durchführen, um jede Tabelle nach Ihrer Migration zu überprüfen. Daher sollte diese Abfrage für Sie funktionieren.


4
@Phil warum? Wenn Sie die Tabellen durchlaufen und von jeder eine teure SELECT COUNT (*) ausführen - wie genau ist das erste Ergebnis, wenn Sie die letzte Tabelle erreicht haben?
Aaron Bertrand

1
Aus Gründen der Klarheit hatte Phil gesagt: "Die Verwendung des Datenwörterbuchs, das keine 100% genauen Ergebnisse liefert, ist ein schlechter Rat. Meiner Meinung nach sollte die Antwort entweder bearbeitet werden, um den Vorschlag zu entfernen, oder gelöscht werden. Denken Sie daran, dass Google nach solchen Antworten sucht und blindlings Ausschneiden und Einfügen ... "Ich stimme zu, dass der Haftungsausschluss wichtig ist (und es gibt angeblich einige Randfälle, in denen die Metadaten keine vernünftigen Ergebnisse liefern). Ich bin nicht der Meinung, dass die Verwendung der Metadatenansichten im Allgemeinen ein schlechter Rat ist.
Aaron Bertrand

5

Hier ist eine SQL Server-Lösung, die COUNT_BIGin einer indizierten Ansicht verwendet wird. Auf diese Weise erhalten Sie eine transaktionskonsistente Zählung ohne den Aufwand für große Tabellen- oder Index-Scans und ohne den für letztere erforderlichen Speicherplatz:

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

Dies erfordert einen einzelnen ersten Scan (kein Weg davon weg) und einen zusätzlichen Aufwand für inkrementelle Tabellendatenmanipulationen. Wenn Sie große Operationen mit vielen Daten ausführen (im Gegensatz zu vielen kleinen Operationen), sollte der Aufwand für Änderungen meiner Meinung nach vernachlässigbar sein.


@SQLKiwi: Wieso werden Lesevorgänge vor 2012 blockiert? SQL Server Fehler?
Jon Seigel

@ JonSeigel - Meine $ 0,05: Normale Clusterindizes für normale Tabellen, die offline erstellt wurden, wenden eine Sch-M-Sperre für Tabellen an. In einer Ansicht ist dies natürlich nicht erforderlich , dies bedeutet jedoch eine Änderung der Operation "Index erstellen", um einen Sonderfall für die indizierte Ansicht zu erstellen, der für SQL2012 durchgeführt wurde. IMHO natürlich.
Fabricio Araujo

3

In Oracle kann ein binärer Baumindex für eine NOT NULL-Spalte verwendet werden, um einen COUNT (*) zu beantworten. In den meisten Fällen ist es schneller als ein FULL TABLE SCAN, da Indizes normalerweise kleiner als ihre Basistabelle sind.

Ein regulärer binärer Baumindex wird jedoch mit 157 Mrows immer noch riesig sein. Wenn Ihre Tabelle nicht gleichzeitig aktualisiert wird (dh nur ein Stapelladevorgang), möchten Sie möglicherweise stattdessen einen Bitmap-Index verwenden.

Der kleinste Bitmap-Index wäre ungefähr so:

CREATE BITMAP INDEX ix ON your_table(NULL);

Null-Einträge werden von einem Bitmap-Index berücksichtigt. Der resultierende Index ist winzig (20-30 8.000 Blöcke pro Million Zeile), verglichen mit einem regulären Binärbaumindex oder der Basistabelle.

Der resultierende Plan sollte die folgenden Operationen zeigen:

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

Wenn Ihre Tabelle gleichzeitig aktualisiert wird, ist ein Bitmap-Index mit einem eindeutigen Wert ein Streitpunkt und sollte nicht verwendet werden.


3

In Oracle wird eine einfache Zählabfrage häufig ausgeführt, indem ein Index anstelle einer ganzen Tabelle gescannt wird. Der Index muss ein Bitmap-Index sein oder in einer Spalte mit der Einschränkung NOT NULL definiert sein. Für komplexere Abfragen, die einen vollständigen Tabellenscan erfordern, können Sie parallele Abfragen verwenden.

Um die parallele Abfrage zu aktivieren (Enterprise Edition erforderlich), können Sie den Optimierungshinweis verwenden:

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

Oder aktivieren Sie die parallele Abfrage für alle Abfragen in der Tabelle:

alter table mytable parallel 12;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.