Буквально безумный ответ, но если у вас настроена какая-то система репликации (для системы с миллиардом строк, я надеюсь, что вы это сделаете), вы можете использовать приблизительную оценку (например, 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)
Таким образом, вместо того, чтобы только селекторы работали в подчиненных, вам нужно будет выполнить вставку, похожий на это:
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 (...)
В конце концов вы должны иметь раба, который существует последним на пути, пройденном графом репликации, относительно первого раба.Это ведомое устройство должно теперь иметь все другие значения счетчика и иметь свои собственные значения.Но к тому времени, как вы закончите, вероятно, будут добавлены строки, поэтому вам нужно будет вставить еще одну, компенсирующую записанный максимальный pk в вашей counter_table и текущую максимальную pk.
В этот момент вывам нужно сделать агрегатную функцию, чтобы выяснить, что такое общее количество строк, но это проще, так как вы будете запускать его не более чем на «число ведомых и изменить ряды».
Если выВ ситуации, когда у вас есть отдельные таблицы в ведомых устройствах, вы можете UNION
получить все необходимые вам строки.
SELECT SUM(cnt) FROM (
SELECT * FROM counter_table_slave_1
UNION
SELECT * FROM counter_table_slave_2
UNION
...
)
Или, знаете, быть немного менее безумным и перенести свои данные враспределенной процессинговой системы, или, возможно, использовать решение для хранилища данных (которое в будущем также даст вам потрясающий перебор данных).
Обратите внимание, это зависит от того, насколько хорошо настроена ваша репликация.Поскольку основным узким местом, скорее всего, будет постоянное хранилище, если у вас нечеткое хранилище или плохо сегрегированные хранилища данных с сильным шумом соседей, это, вероятно, будет работать медленнее, чем просто ожидание одного SELECT COUNT(*) ...
Но если выиметь хорошую репликацию, то ваш прирост скорости должен быть напрямую связан с числом или рабами.Фактически, если для выполнения одного запроса подсчета требуется 10 минут, а у вас есть 8 подчиненных, вы бы сократили свое время до пары минут.Может быть, час, чтобы сгладить детали этого решения.
Конечно, вы никогда не получите действительно удивительно точного ответа, так как это распределенное решение вводит немного времени, когда строки могут быть удалены и вставлены, но вы можете попытаться получить распределенную блокировку строк одновременноэкземпляр и получить точное количество строк в таблице на определенный момент времени.
На самом деле это кажется невозможным, поскольку вы в основном застряли с решением только для SQL, и я не думаю, что у вас есть механизм, позволяющий мгновенно выполнять закрытый и заблокированный запрос для нескольких ведомых.Возможно, если бы вы имели контроль над файлом журнала репликации ... это означает, что вы буквально раскручивали бы рабов для этой цели, что, без сомнения, медленнее, чем просто выполнение запроса подсчета на одной машине.
Итак, мои две копейки 2013 года.