2017-07-16 1 views
1

J'ai une requête de sélection qui appelle une fonction trois fois [bien sûr à chaque fois avec une colonne d'entrée diff]. Je remarque que le temps d'exécution [plusieurs lignes] est de 8 secondes contre 3 secondes lorsque j'appelle la fonction une fois. C'est logique, puisque la charge de travail est triplée.Force le multithreading dans une requête de sélection? [Oracle ou Sql-Server]

DEMANDER:
Est-il possible de faire allusion au serveur DB pour forcer multithread car ils sont 3 différentes colonnes indépendantes?

J'ai essayé d'extraire les résultats séparément et de les joindre. Même ils ne semblent créer aucun type de parallélisme, ni dans SQL-Server ni dans Oracle. En utilisant la syntaxe SS ci-dessous.

select top 200 dbo.CALC_DURATION (Col1, Col2 , 'PP', 553, '', 'N', 'H'), 
       dbo.CALC_DURATION (Col3, Col4 , 'PP', 553, '', 'N', 'H'), 
       dbo.CALC_DURATION (Col5, Col6 , 'PP', 553, '', 'N', 'H') 
from NNMP265_ISS; 

enter image description here extrait de fonction ci-dessus:

+1

Je doute que ce soit possible car CALC_DURATION est une fonction scalaire. Voir https://dba.stackexchange.com/questions/134453/sql-not-engaging-parallelism-for-extremely-large-query – Serg

+0

Pouvez-vous inclure le code de la fonction? Les gens pourraient avoir des idées sur la façon dont cela pourrait être fait d'une autre manière qui n'empêche pas le parallélisme. –

+0

Bien sûr, merci. La fonction calcule les heures de travail en donnant la priorité à deux ensembles de données, puis calcule avec précision les heures de travail entre l'heure de début et celle de fin. Joindre une capture d'écran dans la question principale car je ne pouvais pas adapter le programme ici. – rsreji

Répondre

1

Je ne peux pas répondre par rapport à Oracle: Dans Oracle parallism travaille en ce qui concerne la recherche (et insérer/modifier) ​​lignes. Cela signifie que l'exécution parallèle vous aidera à trouver les résultats - pas sur les routines plsql que vous exécutez sur eux.

Maintenant, voici la partie délicate: Si le résultat d'une routine PL/SQL est nécessaire pour construire l'ensemble de résultats (par exemple WHERE my_function (col1)> 3), il bénéficiera du parallélisme; si la routine est uniquement appliquée pour "embellir" le résultat final (par exemple SELECT my_function (col3), cela ne sera pas le cas car cela ne se produira pas dans l'exécuteur PX.)

Vous pouvez essayer de tromper l'optimiseur pour exécuter votre fonction en parallèle en utilisant des astuces de matérialisation ou en se cachant sous plusieurs niveaux de sous-requêtes mais je recommande sérieusement de ne pas le faire.Le comportement de l'optimiseur n'est pas stable même à travers une version mineure et pourrait soudainement se comporter complètement après une mise à jour.

La meilleure façon de résoudre votre problème est d'éviter d'appliquer PL/SQL à un ensemble de résultats et de réécrire votre requête pour n'utiliser que le langage SQL, ce qui est particulièrement vrai puisque vous évitez les coûts. de basculer entre SQL et les contextes PL/SQL.

1

J'ai le même problème que vous. J'ai une fonction scalaire pour calculer la route de voiture entre deux points

Donc le temps de traitement est linéaire, un calcul dure 8 ms mais 1000 calculs nécessitent 8 secondes.

Je ne pouvais pas faire fonctionner le parallélisme en postgre sql donc je fais une fonction C# pour envoyer plusieurs requêtes à db en utilisant 4 threads je réduis en fait le temps total de 8 secondes à 2 secondes.

Vous pouvez voir une référence à mon code ici:

https://codereview.stackexchange.com/questions/155253/splitting-a-list-of-numbers-into-multiple-lists

la fonction Mise au point routeParallelGenerationroute_source ont l'info besoin pour calculer l'itinéraire.

+0

Merci pour l'idée. Juan. – rsreji