sql >> データベース >  >> RDS >> Sqlserver

SQLServerのカウントが遅い

    非常に近い概算(実行中のトランザクションを無視)は次のようになります:

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

    これにより、COUNT(*)よりもはるかに高速に返されます。 、そしてテーブルが十分に速く変化している場合、それは実際にはそれほど正確ではありません-COUNTを開始したとき(およびロックが取得されたとき)とテーブルが返されたとき(ロックが解放されて待機中のすべての書き込みトランザクション)の間にテーブルが変更された場合テーブルへの書き込みが許可されました)、それははるかに価値がありますか?そうは思いません。

    カウントしたいテーブルのサブセットがある場合(たとえば、WHERE some_column IS NULL )、その列にフィルター処理されたインデックスを作成し、それが例外であるかルールであるかに応じて、where句をいずれかの方法で構造化できます(したがって、小さいセットでフィルター処理されたインデックスを作成します)。したがって、次の2つのインデックスのいずれか:

    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;
    

    次に、次を使用して同様の方法でカウントを取得できます:

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

    反対のことを知りたい場合は、上記の最初のクエリから差し引くだけです。



    1. MySQLでデータベースを作成する方法

    2. IDが最小のレコードを削除する

    3. iOSの緯度と経度のphpクエリがxml出力で近くのmysqllatとlonを検索していません

    4. oci8、php7およびOracle10.1の互換性