2009-08-06 21 views
0

件名ごとに、テーブルスキャンを行わずにテーブルのレコードを高速でカウントする方法を探していますSQL Serverの条件でテーブルレコード数を取得する最速の方法

+0

あなたはさらにビットをしてください説明してもらえますか?あなたはちょうど探していますか: tablename からカウント(*)を選択してくださいおそらく "with(notol)" –

+0

私はレコードの数を選択する必要がある大テーブル。 active = 1のユーザーからcount(id)を選択する 全テーブルスキャンを行わずにレコードをカウントする方法を探していますが、sysインデックスからすべてのレコード数を取得するサンプルが見つかりましたが、可能な条件 – nLL

+0

@nLL:この追加情報を追加するには、質問を編集する必要があります。 –

答えて

2

単純に、テーブルは、where条件に対して正しく索引付けされます。

あなたは、パフォーマンスのこの種の上に気になる場合のアプローチは、あなたのテーブルがのfooの主キーが含まれている場合、たとえば、問題のフィールドを組み込むインデックスを作成することで、その後、バーオウムをフィールドそして植え込みとあなたが定期的にちょうどあなたが[低木FOOの複合インデックスを設定する必要があり、このフィールドからのデータを必要とする低木に基づいた条件を使用してレコードを引き戻すために必要になるだろうことを知っています]。このようにして、rdbmsは、テーブルではなくインデックスのみを照会する必要があります。ツリー構造であるインデックスは、テーブル自体よりもはるかに高速にクエリできます。

rdbmsが実際にどのくらいのアクティビティを必要とするかは、rdbms自体と、どの情報がインデックスに格納されるかによって異なります。たとえば、レコード・カウントが表レベルで保持され、表スキャンが不要なため、where条件を使用しない非索引付けされた表では、select count()*がほとんどのrdbmsの戻り値になります。索引アクセスについても同様の考慮事項があります。

インデックスを更新すると、フィールドを含むすべてのインデックスも更新する必要があるという点で、インデックスはメンテナンスオーバーヘッドを伴うことに注意してください。これは重大な考慮事項であるかもしれませんが、ほとんどのアクティビティーが読み取られ、挿入/更新/削除アクティビティーの重要性が低い表を見ることは珍しくありません。インデックスは実際のテーブルデータ自体には触れません。

ADDED:重要なIUDアクティビティを持つテーブルでインデックスアクセスを使用している場合は、定期的なメンテナンスをスケジュールしていることを確認してください。ツリー構造、すなわち索引は、均衡が取れているときに最も効率的であり、重要なUID活動では、このようにするために定期的な保守が必要です。

+0

ありがとうございます。私のテーブルには多くの挿入/削除アクティビティ(約50k-60k /日)があります。私はあなたの返事の後半部分で説明したことを知っていますが、私は正しく(英語は母国語ではありません) – nLL

+0

50-60kはあまりありません。 24時間で86400秒があるので、1秒間に1回の変更より少ない60,000を取ります(このアプリは1日を通して均等に使用されていると仮定します)。ピーク時は何ですか?アプリが使用されていないときはありますか? テーブルスキーマを知らなくても、指定されたインデックスが良いかどうかを示す使用パターンなどは行えません。 一般的なアドバイス:表の索引の数を最小限にし、その表の列の数を重要なものだけに保ちます。 –

+0

@rangerchris - テーブル上のインデックスの数を最小限に抑えることができます。これは、困難なビットである特定の状況のセットに対して最も効果的なインデックスセットに到達するだけであり、最小値は必ずしも1ではありません。 – Cruachan

2

異なる方法がありますが、最も信頼性の高い1が

Select count(*) from table_name 

しかし、あなたはまた、最後の2の必要性を実行、更新するsysindexesに次のいずれか

select sum(1) from table_name 

select count(1) from table_name 

select rows from sysindexes where object_name(id)='table_name' and indid<2 

exec sp_spaceused 'table_name' 

DBCC CHECKTABLE('table_name') 

を使用できること以外にありこれを達成するために次のことを行ってください。更新しないと間違った結果が出る可能性が高いですが、近似のために実際に動作する可能性があります。

DBCC UPDATEUSAGE ('database_name','table_name') WITH COUNT_ROWS. 

EDIT:申し訳ありませんが、私は特定の条項でカウントについての部分を読んでいませんでした。私はCruachanに同意します。あなたの問題の解決策は適切なインデックスです。

2

以下のページは、テーブルの行数を精度とスピードの点で解説する4つの方法を示しています。

http://blogs.msdn.com/b/martijnh/archive/2010/07/15/sql-server-how-to-quickly-retrieve-accurate-row-count-for-table.aspx

これは、1つの管理Studioを使用しています:

SELECT CAST(p.rows AS float) 
FROM sys.tables AS tbl 
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2 
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) 
AND p.index_id=idx.index_id 
WHERE ((tbl.name=N'Transactions' 
AND SCHEMA_NAME(tbl.schema_id)='dbo')) 
関連する問題