最近、私はデータベースのパフォーマンス改善プロジェクトに取り組んでいました。そこにある1つのストアドプロシージャが問題を引き起こしていました。そのコードでは、クエリが行数を入力し、その値をローカル変数に格納しました。そのクエリは大きなテーブルをスキャンしていました。そのため、リソース使用率が大幅に高くなりました。この問題を修正するために、障害のあるコードを削除し、SQLServerカタログビューを使用してテーブルの行数を生成しました。
SQLServerのテーブルの行数をカウントする方法はいくつかあります。この記事では、常に正しい方法を選択できるように説明します。
次のいずれかの方法で、テーブルの行数を取得できます。
- COUNT()関数を使用します。
- SQLServerカタログビューの組み合わせ。
- sp_spaceusedの使用 ストアドプロシージャ。
- SQL ServerManagementStudioの使用。
もっと深く掘り下げましょう。
COUNT(*)またはCount(1)を使用して行数を取得する
COUNT(*)またはCOUNT(1)関数を使用できます–これら2つの関数によって生成される結果は同じです。
行数を取得するには、最初にCOUNT(*)を使用してクエリを実行します。デモンストレーションの目的で、STATISTICSIOの値をONに設定しました。
USE wideworldimporters
go
SELECT Count(*)
FROM tblcustomer
go
出力:
IO統計:
Table 'tblCustomer'. Scan count 1, logical reads 691, physical reads 315, page server reads 0, read-ahead reads 276, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
ご覧のとおり、SQL Serverは、結果を満たすために691個の論理読み取りを実行する必要があります。
それでは、COUNT(1)を使用してクエリを実行しましょう:
USE wideworldimporters
go
SELECT Count(1)
FROM tblcustomer
go
出力:
IO統計:
Table 'tblCustomer'. Scan count 1, logical reads 691, physical reads 687, page server reads 0, read-ahead reads 687, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
この場合も、SQL Serverは、結果を満たすために691個の論理読み取りを実行する必要があります。
カウント(1)はカウント(*)関数よりも速いという意見があることに言及する必要があります。ただし、上記の例でわかるように、結果セットとIO統計は同じです。したがって、任意の方法を使用してテーブルの行数を生成できます。
長所:
COUNT関数は、テーブルから正確な行数を入力します。
短所:
COUNT関数を実行すると、テーブルがロックされます。テーブルにアクセスする他のクエリは、結果が生成されるまで待機する必要があります。数百万行のテーブルがあるビジーなシステムで作業している場合は、テーブルの正確な行数を入力する必要がない限り、営業時間中にCOUNT関数を実行しない方がよいでしょう。
SQLServerカタログビューの組み合わせ
次の動的管理ビューでSQLServerカタログビューを使用できます。
- sys.tables –テーブルのリストにデータを入力します。
- sys.indexes –テーブルのインデックスのリストにデータを入力します。
- sys.partitions –各パーティションの行にデータを入力します。
行数を取得するには、次のスクリプトを実行します。
SELECT a.NAME,
c.NAME,
Sum(b.rows)
FROM sys.tables a
INNER JOIN sys.partitions b
ON a.object_id = b.object_id
INNER JOIN sys.indexes c
ON b.index_id = c.index_id
AND b.object_id = c.object_id
WHERE a.object_id = Object_id('tblCustomer')
AND c.index_id < 2
出力:
クエリはテーブル名に入力されます 、インデックス名、 および合計行 すべてのパーティションで。
それでは、IO統計を確認しましょう:
Table 'syssingleobjrefs'. Scan count 3, logical reads 6, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'sysidxstats'. Scan count 1, logical reads 6, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'sysschobjs'. Scan count 0, logical reads 4, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'sysrowsets'. Scan count 2, logical reads 14, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
ご覧のとおり、クエリは30回の論理読み取りのみを実行します。
長所:
このアプローチは、COUNT関数よりも高速です。ユーザーテーブルのロックを取得しないため、ビジー状態のシステムで使用できます。
短所:
このメソッドは、おおよその行数を入力します。 sys.partitionsのMicrosoftドキュメントでは、 rows columnは、パーティションのおおよその行数を示します。
したがって、COUNT関数よりも高速に結果をもたらすクエリを探している場合は、これを使用できます。ただし、結果は不正確になる可能性があります。
sp_spaceusedを使用
sp_spaceused 行数とともに手順は、次の詳細を提供します:
- 名前 –テーブル名
- 行 –テーブル内の行の数。
- 予約済み –テーブルの予約済みスペースの合計。
- データ –テーブルで使用される合計スペース。
- Index_size –インデックスで使用される合計スペース。
- 未使用 –使用されていないテーブルの予約済みスペースの合計。
構文は次のとおりです。
EXEC Sp_spaceused 'database_name.schema_name.table_name'
クエリ:
EXEC Sp_spaceused 'WideWorldImportors.dbo.tblCustomer'
出力:
SQL ServerManagementStudioを使用する
テーブルの行数を取得するには、SQLServerManagementStudioを使用できます。
SQL ServerManagementStudioを開きます>データベースインスタンスに接続します>テーブルを展開します>tblCustomerを右クリックします>プロパティ
表 プロパティ ウィンドウで、ストレージをクリックします 。 行数が表示されます 右側の値:
テーブルの行数を取得する別のオプションには、SQLCompleteSSMSアドインが付属しています。この機能拡張により、オブジェクトエクスプローラウィンドウでテーブル名にマウスを合わせると、ヒントに推定行数が表示されます。このようにして、追加の作業なしでビジュアルモードで必要なデータを取得できます。
結論
この記事では、特にテーブルの合計行数を計算するためのさまざまなアプローチについて説明しました。
- COUNT関数を使用します。
- さまざまなカタログビューを組み合わせる。
- sp_spaceusedの使用 ストアドプロシージャ。
- SQL ServerManagementStudioの使用。
1つの方法だけに固執する必要はありません。それぞれのバリエーションには固有性があり、状況に最も適したものを適用できます。