文字通り非常識な答えですが、なんらかのレプリケーションシステムがセットアップされている場合(10億行のシステムの場合はそうすることを望みます)、ラフな推定値(などMAX(pk)
)を使用して、その値をスレーブの数で除算できます。複数のクエリを並行して実行します。
ほとんどの場合、次のような方法で、最良のキー(または私が推測する主キー)に基づいてスレーブ間でクエリを分割します(行/スレーブとして250000000を使用します)。
-- First slave
SELECT COUNT(pk) FROM t WHERE pk < 250000000
-- Ith slave where 2 <= I <= N - 1
SELECT COUNT(pk) FROM t WHERE pk >= I*250000000 and pk < (I+1)*250000000
-- Last slave
SELECT COUNT(pk) FROM t WHERE pk > (N-1)*250000000
しかし、必要なのはSQLだけです。なんとバスト。では、あなたがサドマゾだとしましょう。マスター(または最も近いスレーブ)では、おそらくこのためのテーブルを作成する必要があります。
CREATE TABLE counter_table (minpk integer, maxpk integer, cnt integer, slaveid integer)
したがって、スレーブでselectを実行するだけではなく、次のように挿入を行う必要があります。
INSERT INTO counter_table VALUES (I*25000000, (I+1)*250000000, (SELECT COUNT(pk) FROM ... ), @@SLAVE_ID)
スレーブがマスターのテーブルに書き込む際に問題が発生する可能性があります。あなたはもっともっと悲しいことをする必要があるかもしれません-つまり、創造的です:
-- A table per slave!
INSERT INTO counter_table_slave_I VALUES (...)
最後に、最初のスレーブに対して、レプリケーショングラフが通過するパスの最後に存在するスレーブが必要です。そのスレーブは、他のすべてのカウンター値を持ち、独自の値を持つはずです。しかし、完了するまでに行が追加されている可能性があるため、counter_tableに記録されている最大pkと現在の最大pkを補正する別の行を挿入する必要があります。
その時点で、総行数を把握するために集計関数を実行する必要がありますが、多くても「所有および変更しているスレーブの数」行で実行するため、簡単です。
スレーブに個別のテーブルがある状況では、次のことができます UNION
必要なすべての行を取得ます。
SELECT SUM(cnt) FROM (
SELECT * FROM counter_table_slave_1
UNION
SELECT * FROM counter_table_slave_2
UNION
...
)
または、少し気が狂って、データを分散処理システムに移行するか、データウェアハウジングソリューションを使用することもできます(これにより、将来、すばらしいデータ処理が可能になります)。
これは、レプリケーションが適切に設定されているかどうかに依存することに注意してください。プライマリボトルネックは永続的なストレージである可能性が最も高いため、不安定なストレージや、近隣のノイズが大きいデータストアの分離が不十分な場合、単一の待機よりも実行速度が遅くなる可能性があります。SELECT COUNT(*) ...
しかし、適切なレプリケーションがある場合、速度の向上は、スレーブの数または数に直接関係するはずです。実際、カウントクエリだけを実行するのに10分かかり、8つのスレーブがある場合、時間は数分未満に短縮されます。このソリューションの詳細を解決するのに1時間かかるかもしれません。
もちろん、この分散解法は行を削除して挿入できる少しの時間を導入するため、驚くほど正確な答えは得られませんが、同じインスタンスで行の分散ロックを取得して正確な数を取得することができますテーブル内の特定の瞬間の行の。
基本的にはSQLのみのソリューションで立ち往生しているため、実際にはこれは不可能に思われます。シャードされてロックされたクエリを複数のスレーブ間で即座に実行するメカニズムが提供されていないと思います。多分あなたがレプリケーションログファイルの制御を持っているなら...それは文字通りこの目的のためにスレーブをスピンアップすることを意味します、それはとにかく単一のマシンでカウントクエリを実行するよりも遅いでしょう。
2013年のペニーが2つあります。