sql >> Databáze >  >> RDS >> Sqlserver

SQL Server Count je pomalý

Velmi blízká přibližná hodnota (ignorování všech transakcí během letu) by byla:

SELECT SUM(p.rows) FROM sys.partitions AS p
  INNER JOIN sys.tables AS t
  ON p.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON s.[schema_id] = t.[schema_id]
  WHERE t.name = N'myTable'
  AND s.name = N'dbo'
  AND p.index_id IN (0,1);

To se vrátí mnohem, mnohem rychleji než COUNT(*) a pokud se vaše tabulka mění dostatečně rychle, není to ve skutečnosti o nic méně přesné – pokud se vaše tabulka změnila mezi okamžikem, kdy jste spustili COUNT (a byly uzamčeny), a okamžikem, kdy byl vrácen (když byly zámky uvolněny a všechny čekající transakce zápisu nyní bylo dovoleno psát na stůl), je to o to cennější? Myslím, že ne.

Pokud máte nějakou podmnožinu tabulky, kterou chcete spočítat (řekněme WHERE some_column IS NULL ), můžete v tomto sloupci vytvořit filtrovaný index a strukturovat klauzuli where tak či onak, v závislosti na tom, zda se jednalo o výjimku nebo pravidlo (takže vytvořte filtrovaný index na menší sadě). Takže jeden z těchto dvou indexů:

CREATE INDEX IAmTheException ON dbo.table(some_column)
  WHERE some_column IS NULL;

CREATE INDEX IAmTheRule ON dbo.table(some_column)
  WHERE some_column IS NOT NULL;

Potom byste mohli získat počet podobným způsobem pomocí:

SELECT SUM(p.rows) FROM sys.partitions AS p
  INNER JOIN sys.tables AS t
  ON p.[object_id] = t.[object_id]
  INNER JOIN sys.schemas AS s
  ON s.[schema_id] = t.[schema_id]
  INNER JOIN sys.indexes AS i
  ON p.index_id = i.index_id
  WHERE t.name = N'myTable'
  AND s.name = N'dbo'
  AND i.name = N'IAmTheException' -- or N'IAmTheRule'
  AND p.index_id IN (0,1);

A pokud chcete vědět opak, stačí odečíst od prvního dotazu výše.



  1. Jak získat aktuální datum a čas s posunem časového pásma v PostgreSQL

  2. Existuje v MySQL způsob, jak obrátit booleovské pole jedním dotazem?

  3. Export tabulky Oracle do listu Excelu

  4. Podmíněný jedinečný index v databázi h2