Mysql
 sql >> Base de données >  >> RDS >> Mysql

Commencer à afficher les résultats de la requête avant la fin de la requête

Paraphrasant :

Il semble que ce que vous aimeriez, c'est une sorte de système où il peut y avoir deux threads (ou plus) au travail. Un thread serait occupé à récupérer de manière synchrone les données de la base de données et à signaler sa progression au reste du programme. L'autre fil traiterait de l'affichage.

Il n'est pas clair que votre requête renverra 500 000 lignes (en fait, espérons que ce ne soit pas le cas), bien qu'elle doive analyser les 500 000 lignes (et n'ait peut-être trouvé que 23 lignes qui correspondent jusqu'à présent). Déterminer le nombre de lignes à renvoyer est difficile; la détermination du nombre de lignes à balayer est plus simple ; déterminer le nombre de lignes déjà scannées est très difficile.

Ainsi, l'utilisateur a défilé au-delà de la 23e ligne, mais la requête n'est pas encore terminée.

Il y a quelques problèmes ici. Le SGBD (vrai de la plupart des bases de données, et certainement de l'IDS) reste lié jusqu'à la connexion actuelle sur le traitement de la seule instruction. Il est difficile d'obtenir des commentaires sur la progression d'une requête. Vous pouvez consulter les lignes estimées renvoyées au démarrage de la requête (informations dans la structure SQLCA), mais ces valeurs sont susceptibles d'être erronées. Vous devrez décider quoi faire lorsque vous atteignez la ligne 200 sur 23, ou vous n'arrivez qu'à la ligne 23 sur 5 697. C'est mieux que rien, mais ce n'est pas fiable. Il est très difficile de déterminer jusqu'où une requête a progressé. Et certaines requêtes nécessitent une véritable opération de tri, ce qui signifie qu'il est très difficile de prédire combien de temps cela prendra car aucune donnée n'est disponible tant que le tri n'est pas effectué (et une fois le tri effectué, il n'y a que le temps de communication entre le SGBD et l'application pour retarder la livraison des données).

Informix 4GL a de nombreuses vertus, mais la prise en charge des threads n'en fait pas partie. Le langage n'a pas été conçu avec la sécurité des threads à l'esprit, et il n'y a pas de moyen facile de l'adapter au produit.

Je pense que ce que vous recherchez serait plus facilement supporté par deux fils. Dans un programme à thread unique comme un programme I4GL, il n'y a pas de moyen facile de partir et de récupérer des lignes en attendant que l'utilisateur tape d'autres entrées (telles que "faire défiler la page suivante pleine de données").

L'optimisation FIRST ROWS est un indice pour le SGBD ; il peut ou non donner un avantage significatif à la performance perçue. Dans l'ensemble, cela signifie généralement que la requête est traitée de manière moins optimale du point de vue du SGBD, mais la transmission rapide des résultats à l'utilisateur peut être plus importante que la charge de travail sur le SGBD.

Quelque part en bas, dans une réponse très mal votée, Frank a crié (mais s'il vous plaît, ne CRIEZ PAS) :

D'ACCORD. La difficulté ici est d'organiser l'IPC entre les deux processus côté client. Si les deux sont connectés au SGBD, ils ont des connexions distinctes, et donc les tables temporaires et les curseurs d'une session ne sont pas disponibles pour l'autre.

Toutes les requêtes n'aboutissent pas à une table temporaire, bien que le jeu de résultats d'un curseur de défilement ait généralement quelque chose d'approximativement équivalent à une table temporaire. IDS n'a pas besoin de placer un verrou sur la table temporaire supportant un curseur de défilement car seul IDS peut accéder à la table. S'il s'agissait d'une table temporaire normale, il ne serait toujours pas nécessaire de la verrouiller car elle n'est accessible que par la session qui l'a créée.

Peut-être qu'un message d'état plus précis serait :

Searching 500,000 rows...found 23 matching rows so far

Probablement; vous pouvez également obtenir un décompte rapide et précis avec 'SELECT COUNT(*) FROM TheTable' ; cela n'analyse rien mais accède simplement aux données de contrôle - probablement en fait les mêmes données que dans la colonne nrows de la table SMI sysmaster:sysactptnhdr.

Ainsi, engendrer un nouveau processus n'est pas clairement la recette du succès; vous devez transférer les résultats de la requête du processus généré vers le processus d'origine. Comme je l'ai dit, une solution multithread avec des threads d'affichage et d'accès à la base de données séparés fonctionnerait d'une certaine manière, mais il y a des problèmes à le faire en utilisant I4GL car il n'est pas sensible aux threads. Vous devrez encore décider comment le code côté client stockera les informations à afficher.