Une réponse littéralement folle, mais si vous avez mis en place une sorte de système de réplication (pour un système avec un milliard de lignes, je l'espère), vous pouvez utiliser un estimateur approximatif (comme MAX(pk)
), divisez cette valeur par le nombre d'esclaves vous avez, exécutez plusieurs requêtes en parallèle.
Pour la plupart, vous partitionneriez les requêtes entre les esclaves en fonction de la meilleure clé (ou de la clé primaire, je suppose), de cette manière (nous allons utiliser 250000000 comme lignes / esclaves):
-- 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
Mais vous n'avez besoin que de SQL. Quel buste. Ok, alors disons que tu es un sadomasochiste. Sur le maître (ou l'esclave le plus proche), vous auriez probablement besoin de créer une table pour cela:
CREATE TABLE counter_table (minpk integer, maxpk integer, cnt integer, slaveid integer)
Ainsi, au lieu d'avoir uniquement les sélections en cours d'exécution dans vos esclaves, vous devriez faire un insert, semblable à ceci:
INSERT INTO counter_table VALUES (I*25000000, (I+1)*250000000, (SELECT COUNT(pk) FROM ... ), @@SLAVE_ID)
Vous pouvez rencontrer des problèmes avec les esclaves écrivant sur une table sur le maître. Vous devrez peut-être devenir encore plus sadique - je veux dire, créatif:
-- A table per slave!
INSERT INTO counter_table_slave_I VALUES (...)
Vous devriez finalement avoir un esclave qui existe en dernier dans le chemin parcouru par le graphe de réplication, par rapport au premier esclave. Cet esclave devrait maintenant avoir toutes les autres contre-valeurs et devrait avoir ses propres valeurs. Mais au moment où vous avez terminé, il y a probablement des lignes ajoutées, vous devrez donc en insérer une autre compensant le max pk enregistré dans votre counter_table et le max pk actuel.
À ce stade, vous devez effectuer une fonction d'agrégation pour déterminer le nombre total de lignes, mais c'est plus facile car vous l'exécuterez sur au plus le "nombre d'esclaves que vous avez et modifiez".
Si vous êtes dans la situation où vous avez des tables séparées dans les esclaves, vous pouvez UNION
obtenir toutes les lignes dont vous avez besoin.
SELECT SUM(cnt) FROM (
SELECT * FROM counter_table_slave_1
UNION
SELECT * FROM counter_table_slave_2
UNION
...
)
Ou vous savez, soyez un peu moins fou et migrez vos données vers un système de traitement distribué, ou utilisez peut-être une solution de Data Warehousing (qui vous donnera également de superbes données à l'avenir).
Notez que cela dépend de la façon dont votre réplication est configurée. Étant donné que le principal goulot d'étranglement sera probablement un stockage persistant, si vous avez un stockage cruddy ou des magasins de données mal séparés avec un bruit de voisin élevé, cela vous exécutera probablement plus lentement que d'attendre un seulSELECT COUNT(*) ...
Mais si vous avez une bonne réplication, vos gains de vitesse doivent être directement liés au nombre ou aux esclaves. En fait, s'il faut 10 minutes pour exécuter la requête de comptage seule et que vous avez 8 esclaves, vous réduisez votre temps à moins de quelques minutes. Peut-être une heure pour aplanir les détails de cette solution.
Bien sûr, vous n'obtiendrez jamais vraiment une réponse incroyablement précise car cette résolution distribuée introduit un peu de temps où les lignes peuvent être supprimées et insérées, mais vous pouvez essayer d'obtenir un verrou distribué des lignes dans la même instance et obtenir un nombre précis des lignes du tableau à un moment donné.
En fait, cela semble impossible, car vous êtes essentiellement bloqué avec une solution SQL uniquement, et je ne pense pas que vous disposiez d'un mécanisme pour exécuter une requête fragmentée et verrouillée sur plusieurs esclaves, instantanément. Peut-être que si vous contrôliez le fichier journal de réplication ... ce qui signifie que vous feriez littéralement tourner des esclaves à cette fin, ce qui est sans doute plus lent que d'exécuter la requête de comptage sur une seule machine de toute façon.
Il y a donc mes deux sous en 2013.