0

各テーブルの行数を選択するクエリが必要ですが、統計的に更新されません。したがって、そのようなクエリは正確ではありません。

user_tables から table_name, num_rows を選択

複数のスキーマを選択したいのですが、各スキーマには最低 500 個のテーブルがあり、そのうちのいくつかには多くの列が含まれています。それらを更新したい場合は、数日かかります。

サイトから、関数にこのクエリが含まれていることを提案するようにトムに依頼します

'select count(*) from ' || p_tname INTO l_columnValue;

count(*) を使用したこのようなクエリは非常に遅く、高速な結果は得られません。
テーブル内の行数をすばやく取得できるクエリはありますか?

4

3 に答える 3

2

コメントで、空のテーブルを削除 (ドロップ?) したいと言いました。正確なカウントは必要ないが、テーブルが空かどうかだけを知りたい場合は、ショートカット カウントを行うことができます。

select count(*) from table_name where rownum < 2;

オプティマイザは、最初の行に到達すると停止します - 実行計画は「count stopkey」操作を示しています - そのため、高速になります。空のテーブルの場合はゼロを返し、データのあるテーブルの場合は 1 を返します。データの量はわかりませんが、気にしないようです。

もちろん、カウントとドロップの間にはまだわずかな競合状態があります。

これは非常に奇妙なことのように思えます。アプリケーションがテーブルを使用している場合、テーブルが空であっても削除すると何かが壊れます。そうでない場合、それが (おそらく冗長である) かどうかは問題ではなく、関係なく削除することができます。混乱があると思われる場合は、ソース (DDL を含む) コントロールに何らかの作業が必要なようですね。


2 つのスキーマのいずれかのテーブルに行があるかどうかを確認するには、両方からカウントします。ユニオン付きのいずれか:

select max(c) from (
    select count(*) as c from schema1.table_name where rownum < 2
    union all
    select count(*) as c from schema2.table_name where rownum < 2
);

... またはgreatestと 2 つのサブ選択、たとえば:

select greatest(
    (select count(*) from schema1.table_name where rownum < 2),
    (select count(*) from schema2.table_name where rownum < 2)
) from dual;

いずれかのテーブルに行がある場合は 1 が返され、両方が空の場合は 0 のみが返されます。

于 2013-05-13T17:58:49.567 に答える
2

完全な開示: 私は当初、(a) インデックスが作成され、(b) null ではない列を具体的にカウントするクエリを提案していました。COUNT(*)@AlexPoole と @JustinCave は、Oracle がとにかくこれを行うためにa を最適化すると指摘しました (以下のコメントを参照してください) 。そのため、この回答は大幅に変更されました。


統計が最新の場合でも、正確な行カウントに使用すべきではない理由について、ここに良い説明があります。User_Tables

テーブル スキャンではなくインデックス スキャンを実行することでカウントを高速化するために使用できるインデックスがテーブルにある場合、Oracle はそれらを使用します。これにより、カウントが速くなりますが、決して瞬時ではありません。とはいえ、これが正確な数を得るために私が知っている唯一の方法です。

空の (ゼロ行) テーブルを確認するには、Alex Poole によって投稿された回答を使用してください。

于 2013-05-13T17:38:16.903 に答える
0

各テーブルのカウントを保持するテーブルを作成できます。次に、カウントしているメイン テーブルを更新するテーブルごとに、INSERT で実行するようにトリガーを設定します。

DELETE のトリガーも含める必要があります。

于 2013-05-13T17:32:44.813 に答える