Apa yang bisa mempercepat permintaan jumlah SQL?

9

Saat melakukan kueri hitung (agregat) SQL, apa yang dapat mempercepat waktu eksekusi dalam 3 sistem basis data ini? Saya yakin banyak hal dapat mempercepatnya (perangkat keras untuk satu), tapi saya hanya seorang DBA pemula, jadi saya yakin saya akan mendapatkan beberapa jawaban di sini. Saya memigrasi sekitar 157 juta baris ke basis data SQL Server, dan kueri ini memakan waktu selamanya. Tetapi dalam basis data sumber saya Netezza, dibutuhkan beberapa detik.

Sebagai contoh:

Netezza 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL Server 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]
MacGyver
sumber
1
Apakah Anda perlu melakukan ini hanya sekali, atau berulang kali?
Jon Seigel
@JonSeigel kami melakukan beban tambahan, dan kami membandingkan catatan antara sistem basis data setiap hari untuk memastikan jumlah bertambah. Berulang kali.
MacGyver

Jawaban:

10

Netezza adalah alat yang dirancang untuk unggul dalam pemindaian meja besar, jadi itu sebabnya Anda mendapatkan hasil yang begitu cepat pada sistem itu.

Untuk SQL Server Anda, Anda dapat mempercepat penghitungan baris dengan meminta dari 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;

Dalam lingkungan transaksi yang tinggi, DMV ini tidak dijamin akurat 100%. Tetapi dari pertanyaan Anda, sepertinya Anda hanya melakukan penghitungan baris untuk memverifikasi setiap tabel setelah migrasi Anda, jadi pertanyaan ini seharusnya cocok untuk Anda.

Patrick Keisler
sumber
4
@ Mengapa mengapa? Jika Anda mengulangi tabel dan melakukan COUNT PILIH mahal (*) dari masing-masing - seberapa akurat hasil pertama setelah Anda mencapai tabel terakhir?
Aaron Bertrand
1
Untuk kejelasan, Phil mengatakan: "Menggunakan kamus data, yang tidak memberikan hasil akurat 100% adalah saran yang buruk. Menurut pendapat saya, jawabannya harus diedit untuk menghapus saran atau menghapus - ingat orang-orang google untuk jawaban seperti itu dan akan membabi buta potong dan tempel ... "Saya setuju bahwa penafian itu penting (dan diduga ada beberapa kasus tepi di mana metadata tidak memberikan hasil yang masuk akal), saya tidak setuju bahwa menggunakan pandangan metadata secara umum adalah saran yang buruk.
Aaron Bertrand
5

Berikut adalah solusi SQL Server yang menggunakan COUNT_BIGdi dalam tampilan yang diindeks. Ini akan memberi Anda penghitungan yang konsisten secara transaksi tanpa overhead dari tabel besar atau pemindaian indeks, dan tanpa perlu penyimpanan yang diperlukan untuk yang terakhir:

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

Ini akan memerlukan pemindaian awal tunggal (tidak ada jalan keluar dari ini), dan menambahkan sedikit overhead untuk manipulasi data tabel tambahan. Jika Anda melakukan operasi besar dengan banyak data (berbeda dengan banyak operasi kecil), saya pikir biaya tambahan pada perubahan harus diabaikan.

Jon Seigel
sumber
@SQLKiwi: Bagaimana bisa membaca diblokir sebelum 2012? Bug SQL Server?
Jon Seigel
@ JonSeigel - My $ 0,05: Indeks berkerumun normal pada tabel normal dibuat offline menerapkan kunci Sch-M di atas meja. Pada tampilan, tentu saja itu tidak diperlukan tetapi ini berarti perubahan pada operasi Buat Indeks untuk membuat kasus khusus untuk tampilan yang diindeks - yang dilakukan untuk SQL2012. IMHO, tentu saja.
Fabricio Araujo
3

Di Oracle, indeks pohon biner pada kolom NOT NULL dapat digunakan untuk menjawab COUNT (*). Dalam kebanyakan kasus akan lebih cepat daripada FULL TABLE SCAN karena indeks biasanya lebih kecil dari tabel dasar mereka.

Namun, indeks pohon biner biasa masih akan besar dengan 157 Mrows. Jika tabel Anda tidak diperbarui secara bersamaan (mis. Hanya proses pemuatan batch), maka Anda mungkin ingin menggunakan indeks bitmap sebagai gantinya.

Indeks bitmap terkecil akan menjadi seperti ini:

CREATE BITMAP INDEX ix ON your_table(NULL);

Entri kosong diperhitungkan oleh indeks bitmap. Indeks yang dihasilkan akan kecil (20-30 8k blok per juta baris) dibandingkan dengan indeks pohon biner biasa atau tabel dasar.

Rencana yang dihasilkan harus menunjukkan operasi berikut:

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

Jika tabel Anda diperbarui secara bersamaan, indeks bitmap dengan nilai unik akan menjadi titik pertikaian dan tidak boleh digunakan.

Vincent Malgrat
sumber
3

Di Oracle, kueri hitung sederhana sering dijalankan dengan memindai indeks alih-alih seluruh tabel. Indeks harus indeks bitmap atau didefinisikan pada kolom dengan batasan NOT NULL. Untuk kueri yang lebih kompleks yang memerlukan pemindaian tabel penuh, Anda bisa menggunakan kueri paralel.

Untuk mengaktifkan kueri paralel (diperlukan Edisi Perusahaan), Anda dapat menggunakan petunjuk pengoptimal:

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

Atau aktifkan kueri paralel untuk semua kueri di atas meja:

alter table mytable parallel 12;
sjk
sumber