sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server Count er langsom

Meget tæt omtrentlig (ignorerer eventuelle transaktioner under flyvningen) ville være:

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

Dette vil returnere meget, meget hurtigere end COUNT(*) , og hvis din tabel ændrer sig hurtigt nok, er den egentlig ikke mindre præcis - hvis din tabel har ændret sig mellem da du startede din COUNT (og låse blev taget) og da den blev returneret (da låse blev frigivet og alle de ventende skrivetransaktioner nu fik lov til at skrive til bordet), er det så meget mere værdifuldt? Det tror jeg ikke.

Hvis du har en delmængde af tabellen, du vil tælle (f.eks. WHERE some_column IS NULL ), kan du oprette et filtreret indeks på den kolonne og strukturere where-sætningen på den ene eller den anden måde, afhængigt af om det var undtagelsen eller reglen (så opret det filtrerede indeks på det mindre sæt). Så et af disse to indekser:

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;

Så kunne du få optællingen på en lignende måde ved at bruge:

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

Og hvis du vil vide det modsatte, trækker du bare fra den første forespørgsel ovenfor.



  1. SQLSTATE[HY093]:Ugyldigt parameternummer

  2. Autonom transaktion i PostgreSQL 9.1

  3. Introduktion til Oracle Mobile Cloud Service

  4. Omkostningerne ved gratis PostgreSQL-reklame