tag:blogger.com,1999:blog-38923480994077494442024-02-18T20:39:59.965-08:00Blog BI Microsoft de Patrice Harel"Tels sont surtout les comédiens, les musiciens, les orateurs et les poètes. Moins ils ont de talent, plus ils ont d’orgueil, de vanité, d’arrogance. Tous ces fous trouvent cependant d’autres fous qui les applaudissent." ErasmePatrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-3892348099407749444.post-18445128792267321042014-12-09T01:28:00.003-08:002014-12-16T02:07:27.383-08:00Désactiver le drillthrough natif d'Excel<div class="MsoNormal">
Désolé pour ceux que SSAS ne passionne pas, car j'ai tendance à écrire beaucoup d'articles à son sujet (au-delà des billets
pseudo-philosophiques sous couvert de journal personnel ; mais c’est vrai que je commence à apprécier le
fait de raconter ma vie : peut-être le plus court chemin vers mon futur
compte Facebook, avec mon lot d’amis que je n’ai pas vu depuis 10 ans, dont le
parcours de leur vie intime m’est maintenant rendu possible, me prendra certes un peu de temps, mais assouvira
mon voyeurisme débridé que nous pouvons tous maintenant conscientiser sans
rougir en prétextant qu’étant donné que tout le monde le fait, pourquoi pas moi).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Pour en revenir à notre sujet, il existe plusieurs
possibilités pour empêcher les utilisateurs d’Excel d’utiliser le « drillthrough »
natif : celui qui permet par un double-clic sur la cellule d’accéder aux
données fines. Est-il encore utile de préciser que cette action n’est pas
rendue possible sur les membres calculés ? Visiblement oui (dédicace à qui
vous savez).<o:p></o:p></div>
<div class="MsoNormal">
Le moyen le plus propre c’est de le gérer via les rôles de
sécurité, en positionnant le paramètre « Local Cube/Drillthrough Access »
à « None » situé sous l’onglet « Cube ». Attention à la
multiplicité des rôles auxquels peuvent appartenir vos utilisateurs.<o:p></o:p></div>
<div class="MsoNormal">
</div>
<a name='more'></a><br />
<br />
<div class="MsoNormal">
Le second moyen, moins pratique à mettre en œuvre, se situe
directement dans Excel, dans les options de votre tableau croisé dynamique, sous
l’onglet Données (« Data »), en décochant la case Activer l’affichage
des détails (« Enable show details »). On pourra le paramétrer à l’ouverture
d’Excel.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Le dernier moyen, très sale, mais qui de ce fait me fait
marrer, consiste en la création d’une
action dans votre cube, de type « drillthrough », et d’utiliser dans
les colonnes à afficher, des dimensions qui ne recoupe jamais le même groupe de
mesure. Il ne faut pas oublier de passer le paramètre « Default » à « True »
afin que cette action se substitue au « drillthrough » par défaut. L’utilisateur
aura alors un message d’avertissement lui spécifiant qu’un certain attribut se
situe en dehors de la granularité d’un certain groupe de mesure. Pourquoi en
arriver là ? Parce qu’il arrive que l’on n’ait pas le droit de toucher aux
politiques de déploiement d’Excel ou, encore moins compréhensible, aux rôles
SSAS, par ce que ce qui a été mis en place est trop complexe, trop coûteux à
corriger (oui, oui, ça arrive). Dans ce
cas, il reste cette troisième option.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
De ces éléments découle naturellement une seconde question :
pourquoi vouloir désactiver le « drillthrough » ? Tout
simplement parce que des utilisateurs mal informés peuvent décider d’afficher
le CA au global (une seule cellule donc) et de faire malencontreusement un
double clic dessus. Et là, même si le « drillthrough » se limite à un
top 1000 par défaut, sur des bases SSAS volumineuses, je peux vous garantir que
cela va vous poser un problème. J’ai personnellement planté un AS de production
avec cette action : à ce moment, l’instance consommait les 128 Go de RAM.
Excel offre la possibilité d’annuler la requête en cours, mais cela n’a aucun
effet si le « Storage Engine » en est déjà à tenter de remonter les
données depuis le disque : la requête sera effectivement annulée dans
Excel mais l’instance continuera de travailler dessus. Dans ce cas, la seule
solution est de tuer la session via un ordre XMLA Cancel (cf les templates de
SSMS).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<br />
<div class="MsoNormal">
Malgré tout, il faut garder à l’esprit que les rôles de
sécurité et des actions de « drillthrough » correctement définis
sont la meilleure manière de faire.<o:p></o:p></div>
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-77955132737670778282014-12-03T01:55:00.002-08:002015-01-02T06:06:57.789-08:00JSS 2014 - Data mining SSAS et AMLJe profite de cet espace pour vous remercier d'avoir participer aux JSS, que ce fut en tant qu'auditeur, conférencier, organisateur, sponsor et autres.<br />
Je remercie tout particulièrement mes collègues de chez SCOP IT pour leur investissement dans la préparation de cet événement, que cela fut pour assurer des sessions ou la logistique. Il ne nous a manqué que l'investissement financier (sponsoring) que nous regrettons de ne pas avoir assuré cette fois, par oubli, concentrés que nous étions sur la préparation de nos conférences respectives. Ça sera très certainement pour l'année prochaine, dont on espère une édition 2015 qui nous permettra encore une fois, peut-être, de préparer un sujet dans le but de partager le fruit de nos recherches avec vous.<br />
<br />
En attendant les webcasts, vous trouverez les fichiers relatifs à ma session <a href="https://onedrive.live.com/?cid=11D07374EB30D233&id=11D07374EB30D233%21915">ici</a>. Pour rappel, l'objectif était de présenter les bases du data mining sur SSAS et sur Azure Machine Learning. Cette session mériterait bien une petite sœur, qui rentrerait dans les détails de ces deux technologies, chose impossible dans un format d'une heure : il fallait faire des choix et j'ai fait, pour une fois, celui de la simplicité et de la vulgarisation.<br />
<br />
Merci encore à vous et si vous avez la moindre question, remarque, faites vous plaisir.<br />
<br />
Et voici la <a href="https://www.youtube.com/watch?v=2rB7CbCVb1U">session</a><br />
<br />
<br />Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com2tag:blogger.com,1999:blog-3892348099407749444.post-60246632471931391782014-11-05T07:56:00.000-08:002014-11-05T07:56:16.863-08:00Le pourquoi de la SCOP : état d'âme<div class="MsoNormal">
C’est dérangeant cette dualité, ces sentiments
contradictoires que l’on ressent en soi, et qui composent nos journées. Ces
mouvements sinusoïdaux, ces va-et-vient entre l’obligation de s’atteler à
l’achèvement de nos tâches professionnelles et l’irrépressible envie de se
sentir détacher de ces/ses contraintes afin de se permettre de réaliser des
choses plus utiles pour la société, pour le bien commun. Ce constat est appuyé
par le fait que j’estime mon métier, tout du moins dans son format précédent,
comme étant inutile pour le plus grand nombre, mais m’apportant simplement à la
fois un grand confort de vie ainsi qu’un exercice intellectuel certes basique,
mais qui a au moins le mérite d’exister. La polarité qui en découle m’empêche
d’avancer, de prendre des décisions, car je suis invariablement tiraillé par
ces deux domaines que tout oppose ou presque. A moins que nous ne trouvions
finalement le moyen de concilier les deux, accordant tantôt à l’une, tantôt à l’autre
de ces deux factions un effort égal mais parfaitement délimité, de manière à
rendre possible sa progression personnelle et se débarrasser de cette très
désagréable impression de faire du surplace, de rester dans une zone de non
choix permanant, il sera à un moment donné nécessaire de prendre soit l’un,
soit l’autre des embranchements qui se présentent. Mais comment rapprocher ces
deux pôles sans trahir les idéaux de l’un par les objectifs de l’autre ?
De quelle manière peut-on se permettre de travailler pour le sens commun sans en
dévoyer ses principes tout en poursuivant son activité professionnelle, qui dans
mon cas se révèle profondément concurrentielle et qui oblige à un narcissisme
débridé, centrée sur sa progression personnelle au dépend de celle des autres
et donc en contradiction avec l’envie de partage et d’évolution symbiotique? <o:p></o:p></div>
<div class="MsoNormal">
</div>
<a name='more'></a><br /><br />
<div class="MsoNormal">
Partant de là, plusieurs chemins sont donc ouverts, qui permettront
peut-être d’éviter de tomber dans une certaine forme de schizophrénie. La plus
facile, de prime abord, c’est faire le choix de la continuité et poursuivre la
route que nous avons commencé à tracer : il suffit de suivre le sillon.
Mais est-ce que finalement, en poursuivant le creusement de cette tranchée ce
n’est pas pour finir par s’enterrer des regrets de la volonté non
accomplie ? Le risque c’est justement d’avoir choisi la facilité et de
finir par se dire que nous n’avons pas osé exercer notre volonté en tentant le
grand virage, ou tout du moins en y appréhendant son entrée. A partir de
là, la porte est ouverte à une certaine catégorie de jugements que l’on porte
sur soi, dont l’une de celle qui me terrifie le plus à savoir, la
dépréciation de sa propre personne induite par le sentiment de faiblesse dans
l’application de nos résolutions. Afin d’éviter cet écueil, il va falloir se
consacrer corps et âme à l’accomplissement des objectifs que suscite ce choix
et occulter les velléités que nous avions d’entreprendre des démarches ayant un
plus grand but social. Cela permettra une certaine forme d’autosatisfaction et
la sortie de l’ornière dans laquelle nous nous trouvons. Mais est-ce qu’en
faisant ça ce n’est pas renier une partie de soi ?<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Le choix le plus dangereux, ce sera de s’engager
complètement sur l’autre voie et d’écouter ce que nous dicte notre volonté.
Etre capable de faire fi de son environnement actuel, reconstruire le contexte
dans lequel on évolue, évaluer toutes les dépendances afin d’écarter celles qui
sont futiles de celles plus importantes, comme nos relations sociales (amis,
famille) et nos habitudes de vie (mode de consommation, organisation des
journées) avec lesquelles il va falloir composer et trouver des compromis. Ce
changement de paradigme provoquera une perte de repère partielle, nécessitant
un temps d’adaptation que nous ferons subir à notre entourage et à nous-même et
qui, si l’on ne prend pas garde, pourra nous faire renoncer à notre entreprise
et dévaloriser un peu plus encore l’image que l’on se fait de soi, débouchant
sur un terrible constat d’échec dont il sera difficile de se relever, sauf à
avoir tout tenté et être capable de faire le bilan de nos erreurs pour au
final, en sortir grandi. Sommes-nous prêt à prendre ce risque ainsi que tous
les engagements affiliés ?<o:p></o:p></div>
<div class="MsoNormal">
Enfin, l’alternative, à la fois sécurisante et épanouissante
de prime abord, consiste à mener de front à la fois les nécessités de notre
emploi actuel et la poursuite de la construction de cet autre moi sur le temps
qu’il restera de disponible une fois la première partie de son contrat remplie.
L’erreur serait de rester dans le ventre mou de l’indécision, cet état léthargique
dans lequel on se trouve en ce moment, et finalement ne rien changer à la
situation. Pour réussir, il faudra s’astreindre à une liste d’objectifs
clairement définie et au suivi de l’état d’avancement de ces derniers. L’essentiel
dans cette situation, c’est de voir que l’on progresse, peu importe la
direction dans un premier temps. L’exigence de l’orientation naîtra quand on se
sera rassuré sur notre capacité à exercer notre volonté. L’accomplissement de
cette vision est celle qui prendra le plus de temps et le plus d’énergie :
serait-elle réalisable ?<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<br />
<div class="MsoNormal">
Met apparu alors une quatrième solution : la
conciliation des deux, à savoir, poursuivre son activité professionnelle tout
en collant le plus possible à ses convictions personnelles et partager ce
résultat avec d’autres. Nous ne sommes donc plus dans le choix de l’une ou de l’autre,
ni dans le partage de l’exercice de sa volonté afin de progresser dans les deux
domaines en parallèle, mais dans l’accommodement, dans l’harmonisation de deux parties
de notre vie finalement pas si antagonistes que cela, pour peine que nous
prenions le temps de les faire s’accorder jusqu’à un certain point. Reste à
arranger les contours, prendre sur soi concernant les éléments contre lesquels
nous ne pouvons pas lutter pour le moment. C’est dans ce but que nous avons
décidé de créer une SCOP.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
"<span style="background-color: white; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 18px;"><i>Derrière tous mes livres et tous mes exposés, il y a une préoccupation métaphysique qui est évidente. Je n'ai pas cessé de croire, et je croirai de plus en plus - maintenant que je suis vieux - qu'aucune modification structurelle de la Cité n'est suffisante. Cette modification est indispensable; mais on aura beau établir une Cité humaine où l'exploitation sera sinon effacée du moins considérablement diminuée, on aura beau établir un régime fiscal plus juste, on aura beau resserrer la hiérarchie des salaires, on n'obtiendra rien s'il n'y a pas une modification profonde du regard jeté par les hommes sur le monde et sur la vie. Le malheur restera au fond de l'individu humain si cet individu n'a pas une vue du monde qui lui permette de dépasser le désespoir</i>." Henri Guillemin</span></div>
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-84374842071373036862014-09-14T12:06:00.000-07:002014-09-14T12:06:01.353-07:00SQL Saturday 2014
<br />
Les SQL du samedi 2014, à Paris, c'est fini. Les premiers mots de ce post
seront pour les organisateurs (GUSS et autres) qui ont abattu un formidable
travail. Merci à vous.<o:p></o:p><br />
<br />
Ensuite pour mes collègues de SCOP IT et surtout pour Romuald qui a accepté
ma présence à ses côtés pour une session de malade mental : c’est toujours
rassurant d’avoir une personne de cette valeur avec soi.<o:p></o:p><br />
<br />
Puis un autre pour nos auditeurs, certains des plus fidèles d’ailleurs, qui
acceptent d’en prendre plein la tête pendant les sessions.<o:p></o:p><br />
<br />
Et enfin, le dernier mais pas des moindres, pour ce brave PowerPoint qui
nous aide tous les jours à concevoir des diapositives et que l’on occulte
presque systématiquement de nos remerciements. En parlant de cela, notre
présentation est disponible <a href="https://onedrive.live.com/?cid=11D07374EB30D233&id=11D07374EB30D233%21913">ici</a>.<o:p> </o:p><br />
<br />
Si des erreurs se sont glissées dans le document ci-dessus, si des points
restent flous, si vous avez des questions, n’hésitez pas à nous les poser, par
mail ou en commentaire de cet article.<br />
<br />
Rendez-vous aux JSS, les 1<sup>er</sup> et 2 décembre 2014, avec, nous l’espérons,
une nouvelle bizarrerie à vous présenter. D’ailleurs, nous allons éviter cette
fois-ci de proposer une session purement technique sur AS. Si vous avez des
suggestions, nous sommes prêts à les entendre (même si nous avons déjà notre
grosse idée concernant le sujet).<o:p></o:p><br />
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-70022516769971230832014-08-11T03:17:00.001-07:002014-08-11T03:17:50.032-07:00La progression : entre investissement personnel et contexte d'entreprise<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Je reprends un thème que Florian a déjà bien abordé sur son
blog (</span><a href="http://fleid.net/?s=dette+technique"><span style="color: blue; font-family: Calibri;">http://fleid.net/?s=dette+technique</span></a><span style="font-family: Calibri;">
et </span><a href="http://fleid.net/2013/04/29/apres-la-dette-technique-la-dette-sociale-lautre-ennemie-du-patron-de-ssii/"><span style="color: blue; font-family: Calibri;">http://fleid.net/2013/04/29/apres-la-dette-technique-la-dette-sociale-lautre-ennemie-du-patron-de-ssii/</span></a><span style="font-family: Calibri;">)
car je viens d’en discuter quelques minutes avec un jeune consultant ce matin
qui est venu me demander comment il pouvait progresser techniquement dans son métier
(tout ceci me faisant prendre conscience de mon âge avancé).</span></div>
<a name='more'></a><br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Je vais exposer ici une partie de la réponse que j’ai faite
à l’une des remarques de ce consultant quand il m’a dit « qu’il faut
travailler en dehors de ses heures de bureau pour progresser ». Je suis en
partie d’accord avec cette condition qui est toute fois pour moi ni suffisante,
ni nécessaire.</span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Dans ma conception de l’entreprise, en plus des logiques d’intégration
sociale (dans le sens de permettre une avancée de la société) et de rentabilité
(pas exclusivement financière), il y en a un troisième qui a trait à l’investissement
qui doit être mis en place dans le but d’avoir une rétroaction positive sur les
deux premiers. Sachant tout de même que chacun de ces trois périmètres ont une
influence les uns sur les autres : dégager des bénéfices (au sens
comptable cette fois-ci) permet d’accroître son action sociale (investissement
de temps/d’argent dans d’autres entreprises, dons de temps/d’argent à des
organismes, bien-être des employés …), l’action sociale permet de dégager des
bénéfices (image de marque, relations de travail, avancées techniques, nouveaux
clients…) et enfin l’investissement<span style="mso-spacerun: yes;">
</span>permet de dégager des surplus (de temps, d’argent) qui sont ensuite utilisés
pour accroître les deux premiers. La boucle est presque bouclée.</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifP7-o55a5e9cwFHPr5wBkzbBFMz21EtwRfaRs4OLFWygPLUQJ6hNpG_yl9iFfSujK_5mKkBajtA386V6Pk6wWL4kff7YISF_6lR4Z-Xv7QIw3YDdY0zAkgu7qv-i4WAsEMjAMEnZxPg/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifP7-o55a5e9cwFHPr5wBkzbBFMz21EtwRfaRs4OLFWygPLUQJ6hNpG_yl9iFfSujK_5mKkBajtA386V6Pk6wWL4kff7YISF_6lR4Z-Xv7QIw3YDdY0zAkgu7qv-i4WAsEMjAMEnZxPg/s1600/Sans+titre.png" height="294" width="320" /></a></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Ce schéma pourrait être étoffé avec d’autres périmètres,
mais pour notre sujet, nous nous contenterons de cette représentation. Il est à
noter que le lien est unidirectionnel entre les actions sociales que mène l’entreprise
et son investissement : c’est discutable et je suis toujours en train de
remettre en cause le sens de cette relation.</span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">La relation entre les investissements et les bénéfices a été
découplée : la flèche rouge représente l’amorce, à savoir qu’il n’est pas
possible d’entreprendre, au sens large du terme, sans investir (de son temps
et/ou de son argent) et donc sans prise de risque. L’autre flèche symbolise une
partie de la problématique dont il est question dans cet article, mais sur un
périmètre bien délimité à savoir : comment investir sur ses collaborateurs
dans le but d’en retirer des bénéfices ? Cette question est en rapport
direct avec la remarque du consultant dont il est question au début de l’article.
Comment faire progresser son équipe ? Par l’investissement. Ce dernier
doit être d’abord personnel et donc propre aux consultants, mais il doit être
facilité et même catalysé par l’entreprise. Il existe beaucoup de types d’investissements
et nous allons nous concentrer sur deux d’entre eux : la veille
technologique et l’auto-formation.</span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">La veille technologique est un investissement à long terme,
c’est pour cela qu’il est rarement mis en place dans les SSII que nous
connaissons et qui sont pilotées par l’objectif de rentabilité à court terme. C’est
d’ailleurs un problème économique plus global et finalement, une grande partie
de la vision économique actuelle se base sur cette logique de rentabilité à
vue. Il n’y a qu’à constater le niveau d’investissement réalisé par les entreprises
par rapport à celui qui existait il y a une trentaine d’années<sup><span style="font-size: x-small;">1</span></sup>. Il
faut en effet accepter de faire sortir quelques jours les consultants de chez
leur client de manière à ce qu’ils puissent effectuer des recherches sur des
sujets qui pourront par la suite permettre à l’entreprise de s’ouvrir à de
nouvelles perspectives. Cela permet aussi de travailler ensemble, dans un
contexte différent de celui de la clientèle, et c’est toujours bon à prendre
afin de conserver une dynamique de groupe par le biais de la synergie née de
nos recherches communes. C’est pour cela que nous nous accordons du temps (2
jours par mois environ) pour travailler sur ces sujets connexes sur lesquels
nous capitaliserons plus tard, que ça soit par le gain de clients ou la
création de relations de travail. Il ne faut pas perdre de vue que quand je
parle de bénéfice ou de capitalisation, il n’est pas seulement question d’argent,
mais également de connaissances techniques, de relations, d’accomplissement
personnel, etc. </span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">L’auto-formation représente une partie des gains offerts par
la veille technologique : on apprend d’un sujet en faisant des recherches
dessus. Mais il y a également l’auto-formation du personnel de l’entreprise par
le personnel de l’entreprise. On retrouve encore une fois cette notion de
synergie qui nous est chère. Elle passe selon nous par le travail en
collaboration chez nos clients. C’est pour cela que l’on s’attache au maximum à
travailler ensemble ou à se rendre visite régulièrement, ne serait-ce que pour
quelques jours. Nous ne sommes pas les seuls bénéficiaires de cette relation,
nos clients en retirent une grande satisfaction (ouverture sur de nouveaux
sujets, nouvelles perspectives sur des problématiques en cours, …). </span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">J’ai voulu mettre en exergue ici le fait que même si la
progression d’une personne naît de sa volonté et de son investissement
personnel, l’environnement dans lequel elle évolue, ici l’entreprise, doit
servir cette volonté d’évolution. Cela sera souvent positif pour les deux
parties et il faut que les entrepreneurs gardent ce fait en tête. Je continue
de croire que tout n’est pas seulement une question d’argent et qu’il est tout
aussi important d’être à l’écoute de ces partenaires afin qu’ils puissent s’accomplir :
les retours n’en seront que positivement plus importants et pas forcement
estimables financièrement.</span></div>
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;">Je répondrai donc à mon fameux consultant qu’avant de
travailler chez soi, il doit s’assurer que son environnement professionnel est
propice à répondre à ses velléités de progrès et qu’ensuite, il devra adapter
son niveau d’investissement personnel en fonction de ses objectifs. Il faut le
faire en cohérence avec les buts que l’entreprise souhaite atteindre tout de même :
il n’est pas question de faire de la veille technologique sur les flux
migratoires des hirondelles quand on fait du décisionnel (encore que).</span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
</div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
<span style="font-family: Calibri;"><sup><span style="font-size: x-small;">1 </span></sup>Voir les livres de Thomas Piketty, <strong>Le capital
au XXI<sup><span style="font-size: x-small;">ème</span></sup> siècle</strong> ou encore Jim Stanford, <strong>Petit cours d’autodéfense
en économie</strong>, ou encore le blog d’Onubre Einz et cet <a href="https://www.blogger.com/1%20Voir%20les%20livres%20de%20Thomas%20Piketty,%20Le%20capital%20au%20XXIème%20siècle%20ou%20encore%20Jim%20Stanford,%20Petit%20cours%20d’autodéfense%20en%20économie,%20ou%20encore%20le%20blog%20d’Onubre%20Einz%20et%20cet%20article%20http://criseusa.blog.lemonde.fr/2011/12/20/la-logique-dinvestissement-des-pme-pmi-americaine/">article</a></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;">
</div>
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com8tag:blogger.com,1999:blog-3892348099407749444.post-54751011626055316782014-08-08T04:49:00.000-07:002014-08-11T03:09:05.543-07:00Session JSS 2013 : Column Store Index et ROLAPSoyons fous, deux articles dans la même journée. Je me permets de remettre ici la webcast de la session que nous avions animée avec Mr Sauget lors des JSS de décembre 2013 (désolé pour le laps de temps). Objectif? 100 000 vues avant la fin de la semaine.<br />
En attendant, voici : <a href="http://www.youtube.com/watch?v=mRETZOLUZUA">Webcast</a><br />
<br />Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-29840833397495202382014-08-08T04:22:00.001-07:002014-08-11T03:09:10.289-07:00Many-to-Many et agrégations<div class="MsoNormal">
<a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>J’aime beaucoup les Many-to-Many sur SSAS, surtout que la
littérature pour un sujet aussi anodin en apparence est assez conséquente. J’aime
surtout les Many-to-Many quand il faut les expliquer à un utilisateur qui ne
comprend pas pourquoi la somme de ses lignes n’est pas égale à la cellule du
grand total.</div>
<div class="MsoNormal">
Pour illustrer notre sujet du jour, voici une base de
données se proposant de permettre à mon entreprise préférée l’analyse du
montant de ses ventes (FactSale) en fonction des raisons de la vente
(FactSaleReason) et du revenu de ses clients (FactIncome). Imaginons que nous
retournions à un mode de rétribution à la journée, ça facilite un peu l’interprétation
de notre cas d’étude.</div>
<div class="MsoNormal">
</div>
<a name='more'></a><br />
<br />
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgK7a0WdregpvaWNtDIlDDdrzvVd0kmoG0cm1eph2rFz181SdQfh3a9qEmW7cxKHzFSoQ05LcpMD7Z1srMYLF_25Nb4RCoWH5X-pny5bslQYxpZPOY-JkguqCdGj4R-n0LLJndc4JKLA/s1600/Sans+titre1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgK7a0WdregpvaWNtDIlDDdrzvVd0kmoG0cm1eph2rFz181SdQfh3a9qEmW7cxKHzFSoQ05LcpMD7Z1srMYLF_25Nb4RCoWH5X-pny5bslQYxpZPOY-JkguqCdGj4R-n0LLJndc4JKLA/s1600/Sans+titre1.png" /></a></div>
<div class="MsoNormal">
<a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><br /></div>
<div class="MsoNormal">
Etant donné qu’un client peut effectuer plusieurs achats
dans les magasins, qu’il peut avoir plusieurs raisons d’achat pour une vente et
qu’il peut percevoir plusieurs rentrées d’argent par jour (salaire, dividende,
redistribution de la part de l’état), on a donc des Many-to-Many croisées entre
ces trois périmètres d’analyse. Au domaine métier près, c’est une modélisation
que je viens de voir chez un de mes clients. Je vous l’accorde, certain
rapprochement sont tendancieux (l’analyse des raisons de la vente en fonction
du revenu notamment, encore que la corrélation de ces deux éléments n’est pas
neutre).</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT6tvI83ILN4Ztega4gkpNbET4CqGuvb-Act0pf7ZrF0Q3MmANKfG7gyzbEd-Kb0LFwlKAIjwal-vszKKNbHVH-MLJe6toQCchH_UVardIx93FBeDP-SMAad0XDXkKBazdGnvRlVbrWQ/s1600/Sans+titre1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT6tvI83ILN4Ztega4gkpNbET4CqGuvb-Act0pf7ZrF0Q3MmANKfG7gyzbEd-Kb0LFwlKAIjwal-vszKKNbHVH-MLJe6toQCchH_UVardIx93FBeDP-SMAad0XDXkKBazdGnvRlVbrWQ/s1600/Sans+titre1.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Image_x0020_4" o:spid="_x0000_i1029" type="#_x0000_t75" style='width:299.4pt;
height:108pt;visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:\Users\pharel\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png"
o:title="" croptop="12260f" cropbottom="33863f" cropleft="1518f" cropright="34769f"/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></div>
<div class="MsoNormal">
Soit la première analyse permise par mon cube (et connue d’une
bonne partie d’entre vous) : la ventilation du montant de mes ventes en
fonction des raisons d’une vente.</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxwAwyRJz_VsvqNf3Qu76qJ8euquO-tbb_lkGiKpn18HC9wi2v_ufkTeEuRkDv6lcHVI8BG4FOhWY4dQlb6q-bpk3sIFCPe3xtx5AUHNvFbmFlLHOlQ1KuOSQWZdJTI1geeyGkAvUKGg/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxwAwyRJz_VsvqNf3Qu76qJ8euquO-tbb_lkGiKpn18HC9wi2v_ufkTeEuRkDv6lcHVI8BG4FOhWY4dQlb6q-bpk3sIFCPe3xtx5AUHNvFbmFlLHOlQ1KuOSQWZdJTI1geeyGkAvUKGg/s1600/Sans+titre.png" height="86" width="320" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Image_x0020_7" o:spid="_x0000_i1028" type="#_x0000_t75" style='width:240.6pt;
height:64.2pt;visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:\Users\pharel\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png"
o:title="" croptop="13340f" cropbottom="43633f" cropleft="843f" cropright="55711f"/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></div>
<div class="MsoNormal">
On constate une chose habituelle dans le cas d’une
Many-to-Many, à savoir un excès sur la somme des lignes par rapport au grand
total. C’est visible ici sur le mois de janvier. C’est tout simplement du au
fait que pour une vente sur ce mois, il y a eu plusieurs raisons d’achat –
étant donné la complexité importante de ma base, on pourra supputer que la
vente en question vaut 3 et que les raisons de cette vente sont le prix et la
pub. Une fois expliqué à nos utilisateurs favoris, il se passe des mois sans qu’ils
reviennent vers vous en signalant un problème dans les données. Sauf que, après
ce moment de répit, il se passe L’AUTRE cas, à savoir un défaut par rapport à
la somme globale.</div>
<div class="MsoNormal">
Imaginons maintenant une autre analyse : le montant de
mes ventes en magasin en fonction des revenus de mes clients. Il est important
pour l’analyse de savoir par magasin, quel était le revenu du client. C’est le
rôle de la Many-to-Many qui, dans les trois cas suggérés par la base AS, est
construite sur les dimensions Date et Customer. Comme je l’ai expliqué dans un
billet précédent, lorsqu’une Many-to-Many utilisent plusieurs dimensions, alors
toutes les dimensions sont utilisées dans la résolution de la requête (voir :
).</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_5r33OT34Thlho2a3JUQaKZhEo5dISnk31rUsKMKE6UHQy-tqHeK9Uq5tgRmV1OnW0lx1WJFuesDBZ7k5bd13pAb-sAeatgXu2OpHNH3dfsa1vxjGmx9fYoAcrIwLQZjikM2p87vDCg/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_5r33OT34Thlho2a3JUQaKZhEo5dISnk31rUsKMKE6UHQy-tqHeK9Uq5tgRmV1OnW0lx1WJFuesDBZ7k5bd13pAb-sAeatgXu2OpHNH3dfsa1vxjGmx9fYoAcrIwLQZjikM2p87vDCg/s1600/Sans+titre.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Image_x0020_10" o:spid="_x0000_i1027" type="#_x0000_t75" style='width:442.2pt;
height:69pt;visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:\Users\pharel\AppData\Local\Temp\msohtmlclip1\01\clip_image007.png"
o:title="" croptop="13928f" cropbottom="42518f" cropleft="1754f" cropright="32561f"/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></div>
<div class="MsoNormal">
Mes clients dépensent-ils plus quand ils gagnent plus ?
Outre le fait que les données ont été créées à la main et sans aucune attention
portée à leur cohérence, cette question soulève d’autres points en rapport à l’activité
économique du moment (si ça vous intéresse, les sujets autour de l’inflation/déflation
et du taux d’épargne/dépense des ménages
sont à la mode en ce moment).</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Bref, contrairement à la fois dernière, la somme de mes
lignes de revenu est inférieure à la somme globale. L’explication est que tous
les jours, mes clients gagnent de l’argent mais, malheureusement pour mon
entreprise, ils ne vont pas pour autant faire des achats chaque jour. Et ça pour
mes utilisateurs, c’est tout nouveau et même si l’analogie avec mon excès sur
la somme de mes lignes est forte, comprendre un défaut sur cette somme leur est
très compliqué.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Du coup, puisque s’en est trop, puisque pour le défaut sur
la somme est hors du champ de compréhension de mes utilisateurs, comment
puis-je les satisfaire et faire en sorte que la somme globale soit égale à la
somme de mes lignes (il faut bien noter ici que mon utilisateur est catastrophé
car les chiffres qu’il voit ne sont pas bons pour lui et qu’il a à peine
sous-entendu qu’une correction A LA MAIN du total était envisagée). J’avais
commencé à jouer avec du SCOPE dans mon Calculation Script jusqu’à ce que je me
pose la bonne question : que représente ma somme globale, en ligne/colonne
si elle ne reflète pas la somme des lignes/colonnes ? Tout simplement l’agrégation
de mes mesures dans l’espace de cube auxquelles ces cellules appartiennent à
savoir ici, pour la valeur 45 de l’Income du mois de janvier, le ALL de ma
dimension Store et le membre January de mon attribut Month (je passe sous
silence les coordonnées des autres dimensions). Du coup, ce qui me gène c’est d’être
sur le All de la dimension Store. Qu’à cela ne tienne, je vais la filtrer. Je
vais par exemple supprimer de mon analyse les membres Unknown et Store3 pour
lesquels je n’ai pas de valeur :</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBL9kJLKUl3gJaz2oSriMciTMcsn0LCn5pY6NCds0og9NvFrGaSMSkRx9TUQoaxkCpYJBupdpihHmhcVAn-9ZXisOfbmh6vDz9fdECbL1HVMM5y-ky_CcKwdCIsHq0dHXLcYLkc9CKoA/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBL9kJLKUl3gJaz2oSriMciTMcsn0LCn5pY6NCds0og9NvFrGaSMSkRx9TUQoaxkCpYJBupdpihHmhcVAn-9ZXisOfbmh6vDz9fdECbL1HVMM5y-ky_CcKwdCIsHq0dHXLcYLkc9CKoA/s1600/Sans+titre.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<!--[if gte vml 1]><v:shape
id="Image_x0020_13" o:spid="_x0000_i1026" type="#_x0000_t75" style='width:299.4pt;
height:162pt;visibility:visible;mso-wrap-style:square'>
<v:imagedata src="file:///C:\Users\pharel\AppData\Local\Temp\msohtmlclip1\01\clip_image009.png"
o:title="" croptop="13564f" cropbottom="19885f" cropright="48802f"/>
</v:shape><![endif]--><!--[if !vml]--><!--[endif]--></div>
<div class="MsoNormal">
Et maintenant, TADAAAAAA :</div>
<div class="MsoNormal">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTETtZg8_cgjthC3zTayoclv36-ZtOuN9T62an-wqT-URj-aj38p1IqGvNekXXiNSweqT_I2rbMIBtrkIFLUGA8SkvEl4oKELAsuQ7nyX5I9Rqb8h-lLytTJk2gcm51H9dgXKq12bZ2A/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTETtZg8_cgjthC3zTayoclv36-ZtOuN9T62an-wqT-URj-aj38p1IqGvNekXXiNSweqT_I2rbMIBtrkIFLUGA8SkvEl4oKELAsuQ7nyX5I9Rqb8h-lLytTJk2gcm51H9dgXKq12bZ2A/s1600/Sans+titre.png" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Et à ce moment, dans les yeux de mon utilisateur, une
lumière brille. Non pas qu’il ait compris ce que je viens de coucher sur le
doux papier de ce blog et que je me suis évertué à lui expliquer, mais parce qu’il
n’a plus à justifier que la somme de ses lignes est différente de la somme
totale.</div>
<br />
<div class="MsoNormal">
Tout ça pour ça vous dîtes vous, mais la satisfaction de son
client n’a pas de prix. Le goût des choses simples (sur un petit air de Pierre
Bachelet). Mais ça permet surtout de refaire un point sur le fonctionnement des
Many-to-Many.</div>
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com1tag:blogger.com,1999:blog-3892348099407749444.post-38256098997795495832014-02-28T02:09:00.002-08:002014-08-11T03:09:15.110-07:00Nouveau challenge<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blogger.com/blogger.g?blogID=3892348099407749444" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
Cela fait déjà 6 mois, et je n’ai pas encore pris le temps de présenter la nouvelle entreprise pour laquelle je travaille. Remarquez, cela fait un bout de temps que je n’ai rien mis sur ce blog : espérons que j’arrive à améliorer les choses de ce côté-là en 2014.<br />
Avec Charles-Henri et Romuald, nous avons décidé de créer une entreprise (SCOP IT), et cela soulève toujours pas mal de questions : en voici quelques-unes dans le désordre.<br />
<br />
<a name='more'></a><br /><br />
Pourquoi créer une entreprise alors que d’autres acteurs existent déjà ? <br />
Question très ouverte qui mérite plusieurs niveaux de réponse. Premièrement, disons que nous n’arrivions pas à trouver le modèle qui nous convenait. Après avoir passé plus de 20 années cumulées dans des sociétés de services diverses, le constat était bien simple : ça vient d’en haut et ça néglige le bas, soit une organisation hiérarchique monolithique pyramidale qui, de notre point de vue, est dépassée et ne constitue plus le meilleur moyen de travailler ensemble efficacement. Donc, à l’heure de l’avènement des sociétés construites en réseaux notamment autour des technologies Internet (Facebook, Twitter, les Blogs, les jeux de coopération en ligne, etc…), il nous parait bien plus profitable de transposer ce modèle dans notre entreprise afin de maximiser le niveau de collaboration et l’implication des consultants. De ce fait, nous adoptons un management plus horizontal et moins vertical ou nous essayons d’impliquer tous les collaborateurs dans les prises de décision de l’entreprise.<br />
<br />
Bon ça c’est bien joli mais comment ça se met en place chez nous ? <br />
Là encore il y a plusieurs aspects à cette question. Le premier, c’est le refus du salariat tel qu’on le connait. Attention cette notion recouvre beaucoup d’idées et afin d’éviter les amalgames, je vais développer un peu. Quand on dit refus du salariat, il faut comprendre le refus d’une relation hiérarchique rigide qui lie un salarié à une structure via un contrat de travail pour lequel ce salarié met à disposition ses compétences en échange d’une rémunération. Chez SCOP IT, il n’y a pas de rémunération (bien entendu ce dernier élément est constitutif d‘une blague, en fait on se gave comme des cochons). Dans une structure plus classique, le salarié n’a que très peu de marge de manœuvre dans la vie de son entreprise. Certes, on pourra lui faire miroiter une relative influence sur l’organisation de son temps de travail, le choix de ses missions, un peu de temps de R&D, une marge de négociation sur ses conditions de travail (salaire et responsabilité entre autre)… mais dans les faits, ça relève un peu de la vaste supercherie (ça fera plaisir à Romuald). Ces aspects sont le fruit d’une communication exclusive entre le salarié et son manager sur l’axe de la négociation. Mais que pensent les autres collaborateurs du niveau de rémunération général par rapport aux performances économiques de l’entreprise ? Comment sont gérées les plages de temps accordées aux projets (facturées ou non) ? Sont-elles le résultat d’une décision d’un petit groupe de personnes ou d’un ensemble ? Sur quelles activités futures s’engagera la société ? Combien de personnes en décident ? Bref, nous ne souhaitons pas que ces aspects soient appréhendés sur la base de la négociation et nous lui préférons le principe de consensus. Nous ne souhaitons pas que les décisions importantes qui impactent tous les collaborateurs soient le fait d’un petit groupe de personne mais d’une globalité ou du moins, d’une majorité représentative. Si je reprends la définition plus classique du salariat évoquée ci-dessus et que nous la transposons à notre modèle, nous comprenons donc que le salariat est une relation souple et de coopération entre tous les éléments constituant la structure, que cette relation se matérialise juridiquement par un contrat de travail dont les modalités permettent le partage, la mobilité, l’égalité et la transparence et pour lequel collaborateur perçoit une rémunération décidée collégialement en échange de ses capacités à accorder du temps à son entreprise dans le but de faire avancer le groupe auquel il appartient. Avec cette nouvelle approche, tout le monde comprendras rapidement que l’entreprise appartient à tous ses salariés.<br />
<br />
Dans quelle mesure elle appartient à tous les collaborateurs ?<br />
C’est bien simple, tous les salariés ont vocation à devenir associé, c’est-à-dire à participer au capital de l’entreprise. Ainsi, l’entreprise appartient pleinement à ceux qui participent à son évolution. Et nous refusons les capitaux externes à l’entreprise. Notre outil de production nous appartient.<br />
<br />
On parle de transparence, mais toutes les entreprises mettent cela en avant ?<br />
Effectivement, en terme absolu, toutes les entreprises assurent de la transparence à leurs employés. En revanche, relativement et qualitativement, elles n’en ont pas le même niveau. Je vais prendre l’exemple le plus révélateur et qui souvent pose un problème dont tout le monde parle en sous-marin mais jamais ensemble : l’aspect économique. Nous faisons le pari de transmettre tous les chiffres à tous les collaborateurs : que ça soit les niveaux de rémunération, de marges, de dépenses, d’investissements, etc… Si l’un de ces sujets doit être discuté, il le sera par tous les collaborateurs. Sur l’exemple des rémunérations, tous savent ce que chacun gagne et les augmentations sont décidées collégialement. Cela peut paraître bizarre mais nous refusons les négociations individuelles avec le tenant des cordons de la bourse. Chaque cas est analysé de manière collaborative et cela n’empêche pas d’avoir différents niveaux d’augmentation en fonction de l’implication de chacun dans l’entreprise. Nous croyons qu’avec un niveau de communication et de transparence suffisant, tous seront capables de reconnaître qu’un tel s’est investi d’une manière qui lui permette d’obtenir un niveau d’augmentation supérieur à celui des autres. Et croyez-moi, quand on en arrive à ce niveau-là, il n’y a plus aucun soucis de divulgation d’information et de génération de comportements envieux.<br />
<br />
Ok, donc l’entreprise appartient à ses employés, mais qu’en est-il de ses fruits ?<br />
La totalité des bénéfices de l’entreprise sont répartis entre deux postes de dépenses : la trésorerie pour l’investissement et la part travail. Cette répartition se fait sur une base minimale de 16% pour la trésorerie et 25% pour les employés (la part travail). Bien évidemment, le curseur est ajustable au-delà de ces limites afin d’atteindre les 100%. La répartition entre les collaborateurs se fait sur la base des jours de présence dans l’entreprise (facturés ou non) et non pas par rapport à la rémunération ou en fonction des parts dans le capital (dividendes) comme c’est trop souvent le cas. Il ne faut pas se leurrer, nous sommes tous des agents économiques et notre travail, lorsqu’il produit des excédents, doit être rémunéré justement : il nous paraît inconcevable que la distribution des fruits de notre travail se fasse de manière dégressive en partant du haut de la hiérarchie : en bref, chez nous il n’y a pas de patrons ou d’actionnaires qui profitent plus que les autres.<br />
<br />
On nage en pleine démocratie alors ?<br />
En tous les cas, on tente de s’en approcher le plus possible. Mais notre modèle, bien que nous soyons conscients qu’il soit très attractif, a aussi ses limites. Comment décider des missions à engager, des niveaux de rémunération, des investissements, etc., lorsqu’une entreprise comme la nôtre comptera 50 salariés et plus ? Nous avons au sein de SCOP IT des avis différents sur ce sujet. En ce qui me concerne, je pense que nous sommes voués à être relativement peu nombreux, mais donner un chiffre serait illusoire : cela se déterminera de manière empirique.<br />
<br />
Nous avons abordé le sujet sous l’aspect des conditions de travail. Il en reste beaucoup à aborder comme les relations entre les entreprises qui ont choisies un modèle similaire au notre, la forme juridique de notre entreprise (parce que tout ce que je viens de raconter est inscrit dans nos statuts, il y a donc une forme juridique particulière à adopter), les relations avec nos clients, les perspectives d’évolution, le contexte économique, la philosophie du partage, etc.<br />
J’espère juste avoir le temps de le faire avant de changer de boîte (ceci est également constitutif d’une boutade).<br />
<br />Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com4tag:blogger.com,1999:blog-3892348099407749444.post-53478592443023303292013-04-16T02:45:00.001-07:002013-04-16T02:53:09.160-07:00Challenge MDX : Generate, TopCount et restriction sur un set... en 2005<span style="font-family: inherit;">Voici un cas marrant sur lequel nous nous sommes penchés avec Thomas Ricquebourg. Nous avons une dimension produit avec une hiérarchie standard (Marque - SousMarque - Produit), une dimension temps avec une hiérarchie (Année - Mois - Jour), une dimension Géographie (Pays) et enfin un groupe de mesures (Quantité et CA) avec des données au jour.</span><br />
<span style="font-family: inherit;">Le but du jeu c'est de ramener les 5 produits les plus vendus par pays pour un mois et une marque donnés. Première étape dans l'écriture de la requête :</span><br />
<br />
<span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">WITH</span></span> <span style="color: blue;"><span style="color: blue;">SET</span></span> [Top Product] <span style="color: blue;"><span style="color: blue;">AS</span></span> </span><br />
<span style="font-family: inherit;"><span style="color: maroon;"><span style="color: maroon;">GENERATE</span></span></span><span style="font-family: inherit;">(</span><br />
<span style="font-family: inherit;">[Geography].[Country].</span><span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">Members</span></span></span><br />
<span style="font-family: inherit;">,<span style="color: maroon;"><span style="color: maroon;">TopCount</span></span>(</span><br />
<span style="font-family: inherit;">[Product].[Product].</span><span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">Members</span></span></span><br />
<span style="font-family: inherit;">,5 </span><br />
<span style="font-family: inherit;">,[Measures].[Quantity] </span><br />
<span style="font-family: inherit;">)</span><br />
<span style="font-family: inherit;">)</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">SELECT</span></span> [Measures].[Quantity] <span style="color: blue;"><span style="color: blue;">ON</span></span> 0,</span><span style="font-family: inherit;">[Geography].[Country].</span><span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">Members</span></span></span><br />
<span style="font-family: inherit;">*[Product].[Brand].<span style="color: blue;"><span style="color: blue;">Member</span></span></span><br />
<span style="font-family: inherit;">*[Time].[Month].&[201304]<br />*[Top Product] <span style="color: blue;">ON</span> 1</span><br />
<span style="font-family: inherit;"><span style="color: blue;"><span style="color: blue;">FROM</span></span> [MyCube]</span><br />
<br />
<br />
<span style="font-family: inherit;">Cette dernière va poser un(des) problème(s) : Elle ne me retourne pas les produits les plus vendus sur le mois sélectionné ou encore, le nombre de produit par pays ne sera pas toujours le même et ce malgré le TopCount. A votre avis pourquoi? Comment résoudre ce cas (attention, nous sommes en 2005)?</span><br />
<span style="font-family: inherit;">Comme d'habitude, laisser vos avis dans les commentaires.</span><br />
<span style="font-family: inherit;">Encore une fois je le précise, tout le monde peut laisser libre cours à son imagination. Peu importe que les propositions soient plus ou moins bonnes, l'idée de ce genre de billet c'est de faire resurgir des notions générales à partir d'un cas précis.</span>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com3tag:blogger.com,1999:blog-3892348099407749444.post-72510134285025054852013-04-06T07:11:00.002-07:002014-08-08T04:43:00.479-07:00Challenge SQL : Upgrade du DELETE<br />
<span style="font-family: inherit;">Etant donné que je suis en panne d'inspiration pour faire de billets intéressants et qu'en plus je n'en fais déjà pas souvent, je vais me lancer dans une petite suite de problématique que je vais vous adresser, à vous nombreux lecteurs de ce blog (nombreux relativement à mon cercle de connaissances professionnelles, autant dire que mis à part mes collègues, personne ne passe ici).<o:p></o:p></span><br />
<span style="font-family: inherit;"></span><br />
<a name='more'></a><br />
<br />
<br />
<span style="font-family: inherit;">Alors voilà le contexte (plutôt simple pour une première). Nous avons une table de plusieurs centaines de millions de lignes, typiquement une table de fait (dans la grande majorité des cas). Sur cette table, nous souhaitons réaliser une suppression des lignes en fonction du périmètre que nous souhaitons réalimenter : de l’annule et remplace en bonne et due forme. Là, on constate que le lot tourne pendant de longues minutes pour réaliser une opération qui nous semble basique (je précise que c’est un serveur de bourrin derrière). En ajoutant un peu de log (on évite le mode debug de SSIS sur les tables à forte volumétrie car ralentit encore plus l’exécution de vos lots), nous constatons que c’est la phase de DELETE des lignes qui prend du temps. Une suppression de 80 millions de ligne prend presque 3 minutes : c’est beaucoup trop. L’instruction de suppression est la suivante :<o:p></o:p></span><br />
<br />
<div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;">
<span style="color: blue; font-family: Consolas; font-size: 9.5pt;">DELETE</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">FROM</span> <span style="color: teal;">MaTable</span></span></div>
<div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;">
<span style="color: blue; font-family: Consolas; font-size: 9.5pt;">WHERE</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: teal;">DateKey</span> <span style="color: grey;">BETWEEN</span> 20060101 <span style="color: grey;">AND</span> 20061231<o:p></o:p></span></div>
<br />
Nous décidons d’intervenir et de mettre en place un élément de base de données qui nous permettra de réduire fortement ce temps de suppression des lignes. Le temps nécessaire à la mise en place de cette amélioration doit être court et elle doit demander un minimum de gestion après son implémentation. Une fois cette dernière réalisée, nous avons, pour la même instruction, un temps de 45 secondes.<o:p></o:p><br />
<br />
Quelle est cette solution miracle? La première personne à répondre dans les commentaires se verra offrir une bière au prochain <b style="mso-bidi-font-weight: normal;">AfterWork de GUSS</b> qui aura lieu le <b style="mso-bidi-font-weight: normal;">17 avril à 19h</b> au <b style="mso-bidi-font-weight: normal;">Charly-Birdy</b>, 1 place Etienne Pernet, Paris 15ème, Métro Commerce.<br />
<br />
------------------------------------------------------------------------------------------------------------<br />
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<span style="mso-ansi-language: FR;"><br /><span style="font-family: inherit;">Voici la réponse tant attendue. Avant toute chose, merci pour votre participation et bien entendu, tout le monde pouvait jouer. Rappellons lescontraintes : ne pas toucher à la requête de suppression mais faire en sorte, via la mise en place de “quelques chose”, que la suppression des lignes prennent moins de temps. Il fallait également que la mise en place de ce “quelques chose” soit rapide et ne demande pas trop de maintenance à notreDBA préféré.Vu dans les commentaires, le partitionnement et le switch associé offrent effectivement un gain de performance conséquent : c’est même l’idéal. Seulement, il faut modifier la requête initiale et la gestion des partitions demande un travail relativement important par rapport à la solution proposée. De plus attention à la synthaxe suivante qui supprime toutes les lignes de la table :<o:p></o:p></span></span></div>
<div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;">
<span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;">DELETE</span><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">FROM</span> <span style="color: teal;">MaTable</span> <o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;">
<span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;">FROM </span><span lang="EN-US" style="color: grey; font-family: Consolas; font-size: 9.5pt;">(</span><span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;">SELECT</span><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: grey;">*</span> <span style="color: blue;">FROM</span> <span style="color: teal;">MaTable</span><o:p></o:p></span></div>
<div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;">
<span lang="EN-US" style="color: blue; font-family: Consolas; font-size: 9.5pt;">WHERE</span><span lang="EN-US" style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: teal;">DateKey</span> <span style="color: grey;">BETWEEN</span> 20060101 <span style="color: grey;">AND</span> 20061231<span style="color: grey;">)</span> <span style="color: blue;">as</span> <span style="color: teal;">Derivee<o:p></o:p></span></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<span style="mso-ansi-language: FR;"><span style="font-family: inherit;">Prenons maintenant un exemple plus abordable en terme de tests. Soit une table de fait avec 31 millions de lignes. Voici les résultats observés avec les configurations suivantes en corrélation avec vos propositions dans les commentaires (les temps sont en secondes) :<o:p></o:p></span></span></div>
<table border="0" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-bottom: medium none; border-collapse: collapse; border-left: medium none; border-right: medium none; border-top: medium none; mso-border-insideh: none; mso-border-insidev: none; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-yfti-tbllook: 1184;"><tbody>
<tr style="mso-yfti-firstrow: yes; mso-yfti-irow: 0;"><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Configuration<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72.2pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">NonClustered (DateKey)<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 54.85pt;" valign="top" width="73"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Clustered (DateKey)<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 70.3pt;" valign="top" width="94"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Compression (Page)<o:p></o:p></span></span></div>
</td></tr>
<tr style="mso-yfti-irow: 1;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 1<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72.2pt;" valign="top" width="96"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 54.85pt;" valign="top" width="73"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 70.3pt;" valign="top" width="94"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td></tr>
<tr style="mso-yfti-irow: 2;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 2<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72.2pt;" valign="top" width="96"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<span lang="EN-US"><span style="font-family: Calibri;">X<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 54.85pt;" valign="top" width="73"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 70.3pt;" valign="top" width="94"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td></tr>
<tr style="mso-yfti-irow: 3;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 3<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72.2pt;" valign="top" width="96"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 54.85pt;" valign="top" width="73"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<span lang="EN-US"><span style="font-family: Calibri;">X<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 70.3pt;" valign="top" width="94"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td></tr>
<tr style="mso-yfti-irow: 4; mso-yfti-lastrow: yes;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 4<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72.2pt;" valign="top" width="96"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<br /></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 54.85pt;" valign="top" width="73"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<span lang="EN-US"><span style="font-family: Calibri;">X<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 70.3pt;" valign="top" width="94"><div align="center" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: center;">
<span lang="EN-US"><span style="font-family: Calibri;">X<o:p></o:p></span></span></div>
</td></tr>
</tbody></table>
<br />
<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-bottom: medium none; border-collapse: collapse; border-left: medium none; border-right: medium none; border-top: medium none; mso-border-insideh: none; mso-border-insidev: none; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-table-layout-alt: fixed; mso-yfti-tbllook: 1184;"><tbody>
<tr style="mso-yfti-firstrow: yes; mso-yfti-irow: 0;"><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Configuration<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 45.3pt;" valign="top" width="60"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">Elapsed time<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 62.7pt;" valign="top" width="84"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">Logical reads<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: windowtext 1pt solid; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-bottom-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 31.5pt;" valign="top" width="42"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">CPU time<o:p></o:p></span></span></div>
</td></tr>
<tr style="mso-yfti-irow: 1;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 1<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 45.3pt;" valign="top" width="60"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">41<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 62.7pt;" valign="top" width="84"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">9467351<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-top-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 31.5pt;" valign="top" width="42"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">41<o:p></o:p></span></span></div>
</td></tr>
<tr style="mso-yfti-irow: 2;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 2<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 45.3pt;" valign="top" width="60"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">100<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 62.7pt;" valign="top" width="84"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">36142241<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 31.5pt;" valign="top" width="42"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">152<o:p></o:p></span></span></div>
</td></tr>
<tr style="mso-yfti-irow: 3;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 3<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 45.3pt;" valign="top" width="60"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">22<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 62.7pt;" valign="top" width="84"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">323742<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 31.5pt;" valign="top" width="42"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">16<o:p></o:p></span></span></div>
</td></tr>
<tr style="mso-yfti-irow: 4; mso-yfti-lastrow: yes;"><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: windowtext 1pt solid; border-top: #f0f0f0; mso-border-right-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 72pt;" valign="top" width="96"><div class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt;">
<span lang="EN-US"><span style="font-family: Calibri;">Config 4<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; mso-border-left-alt: solid windowtext .5pt; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 45.3pt;" valign="top" width="60"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">77<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 62.7pt;" valign="top" width="84"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">283512<o:p></o:p></span></span></div>
</td><td style="background-color: transparent; border-bottom: #f0f0f0; border-left: #f0f0f0; border-right: #f0f0f0; border-top: #f0f0f0; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 31.5pt;" valign="top" width="42"><div align="right" class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; text-align: right;">
<span lang="EN-US"><span style="font-family: Calibri;">70<o:p></o:p></span></span></div>
</td></tr>
</tbody></table>
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeLG7v0PYHgBtny3a5ylhmxS46XWdFSh0gaoX2_3anG91Vit6SJIawnkfMecP_z_lmVQBSZLXKQ3evT35571aWRmbf9QpAQDDq9el_zV_G4q5Zu0ytZoWEJFJnyM7xgR4ex95deSMAzg/s1600/Sans+titre.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" bua="true" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeLG7v0PYHgBtny3a5ylhmxS46XWdFSh0gaoX2_3anG91Vit6SJIawnkfMecP_z_lmVQBSZLXKQ3evT35571aWRmbf9QpAQDDq9el_zV_G4q5Zu0ytZoWEJFJnyM7xgR4ex95deSMAzg/s640/Sans+titre.png" /></a></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<span style="font-family: inherit;">Pourquoi un tel écart entre la heap table, le non clusterd index et le clusterd index compressé? </span><a href="http://www.blogger.com/null" name="_GoBack"></a><span style="font-family: inherit;">Le non clustered index nécessite de supprimer les lignes dans la tables et les entrées dans l’index. Lorsqu’une table est compressée par page, SQL Server met en place quelques objets supplémentaires pour gérer cette compression et notamment un page dictionnary qui a grosso modo le même mode d’organisation que ceui d’Xvelocity (appliqué au column store index et à Tabular). Passé un certain seuil de nombre de ligne à supprimer/mettre à jour (je ne connais pas le mode de calcul de ce seuil interne au moteur, si quelqu’un peut nous renseigner, nous sommes preneur), SQL Server doit recréer ce dictionnaire de données.</span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<br /></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<span style="mso-ansi-language: FR;"><span style="font-family: inherit;">Au final, un clustered index sans compression constitue la solution répondant à notre problématique.<o:p></o:p></span></span></div>
<div class="MsoNormal" style="margin: 0cm 0cm 8pt;">
<span style="mso-ansi-language: FR;"><span style="font-family: inherit;">Tout cela pour mettre en évidence le fait de ne pas oublier que les clusterd index ne servent pas qu’aux SELECT : ce sont des éléments indispensables de toutes vos tables (les heap tables sont très rarement avantageauses). Attention, cet exemple ne tend pas à démontrer qu’il faut orienter la création de vos clustered index uniquement en fonction des DELETE, mais ces opérations sont à prendre en considération quand leur nombre devient important et quand elles gèrent de grands volumes de données.<o:p></o:p></span></span></div>
<br />
<span style="font-family: inherit;">Les références :</span><br />
<a href="http://technet.microsoft.com/en-us/library/cc917672.aspx#EDAA">http://technet.microsoft.com/en-us/library/cc917672.aspx#EDAA</a><br />
<a href="http://msdn.microsoft.com/en-us/library/dd894051(v=sql.100).aspx">http://msdn.microsoft.com/en-us/library/dd894051(v=sql.100).aspx</a><br />
<a href="http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/01/18/details-on-page-compression-page-dictionary.aspx">http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/01/18/details-on-page-compression-page-dictionary.aspx</a>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com7tag:blogger.com,1999:blog-3892348099407749444.post-25105370047589749132013-02-01T07:29:00.003-08:002013-02-01T07:30:30.304-08:00Slides des JSS disponiblesEtant donné que je viens de m'aperçevoir que j'avais un Skydrive et que je viens juste d'apprendre à m'en servir, je suis heureux de partager avec vous les slides de la session "Stratégies de processing SSAS 2012" animée au JSS 2012 par David Tang et moi-même.<br />
<br />
<a href="https://skydrive.live.com/?cid=6836C19F017DA8FF">https://skydrive.live.com/?cid=6836C19F017DA8FF</a><br />
<br />
A dispo si vous avez des questions ou des remarquesPatrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-64211230169423702462013-01-30T01:00:00.001-08:002013-01-30T01:03:14.912-08:00Composant "poubelle" dans vos DataFlow<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span lang="FR" style="mso-ansi-language: FR;">Il arrive de temps en temps que,
sous BIDS, nous redirigions la sortie d’erreur de nos composants (et donc les
lignes du flux) vers un composant « poubelle » : ce <span style="mso-spacerun: yes;"> </span>fameux colonne dérivée qui ne sert à rien. Ce
qu’il faut savoir, c’est qu’une fois notre lot lancé avec DTEXEC, donc en
dehors du mode debug, le processus va chercher à optimiser le lot en supprimant
du Data Flow les composants qui ne servent à rien, donc notre Derived Column « poubelle ».
Dit comme cela, rien de bien méchant. Sauf quand votre Data Flow utilise un
composant Script qui lit un fichier plat en tant que source et que le message
d’erreur est le suivant :<o:p></o:p></span><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVnkpqNdy5H72iGVz2SgW-npJVRE6URSN6U0DKbdiOSVN6xa059JPmeykC-rPmAlefBwpO06DUTiN6qbC4GXTtjIzWeX4DJ1WxXDIJ7hSi6UPCqqrTBEQHSqx8fs9jgGgLlE31wEVa_w/s1600/erreur.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="315" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVnkpqNdy5H72iGVz2SgW-npJVRE6URSN6U0DKbdiOSVN6xa059JPmeykC-rPmAlefBwpO06DUTiN6qbC4GXTtjIzWeX4DJ1WxXDIJ7hSi6UPCqqrTBEQHSqx8fs9jgGgLlE31wEVa_w/s640/erreur.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span lang="FR" style="mso-ansi-language: FR;">Du coup, on pense à un souci avec
le stream de notre Script, puis à un problème de synchronisation des entrées et
des sorties, puis que SSIS a un bug, on « google-ise » sur
System.Runtime.InteropServices.COMException, sur le HResult 0xC0047020, etc. En
fait, c’est juste que DTEXEC ne sait pas quoi faire des lignes redirigées vers
la sortie d’erreur.<o:p></o:p></span><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span lang="FR" style="mso-ansi-language: FR;">Moralité : attention à la signification réelle des messages d’erreur SSIS (mais ça on le savait déjà) et pensons à gérer
correctement les lignes que notre flux ne peut pas assimiler. Plusieurs raisons
à cela. A la vue de cet exemple, ça peut poser des soucis à l’exécution.
Ensuite, cette information mal formatée peut être utile à votre client et doit
lui être remontée d’une façon ou d’une autre (une table de log par exemple).<o:p></o:p></span><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-1610853735834365572012-11-29T05:42:00.001-08:002012-11-29T05:43:20.711-08:00Impossible de trier les rapports en vue détailléeOn m'a remonté que, sur quelques répertoires du serveur de rapports (SSRS 2008 R2) il était impossible de trier les rapports en fonction des colonnes disponibles lorsque nous sommes en mode vue détaillée (Details View). Comme quoi, on exploite vraiment toutes les fonctionnalités de RS pour le projet sur lequel je travaille actuellement.<br />
En cherchant un peu, et en utilisant les Developper Tools d'IE, on remarque que c'est toujours la même fonction Javascript qui plante. On se prend une erreur <span style="color: #1122cc;">Error 1006, expecting ')'</span><br />
Mes connaissances dans ce domaine étant assez largement limitées, j'y vais à tâtons pour découvrir empiriquement que ce sont les répertoires RS avec une quote qui empêchent les utilisateurs d'ordonner leurs rapports.<br />
Donc si jamais vous rencontrez ce problème, vous avez maintenant une solution (il suffit de supprimer les quotes), parce qu'àprès avoir cherché un peu de documentation là-dessus, je n'ai rien trouvé. Si vous avez plus d'information à ce sujet, je suis preneur.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-90029995303759058522012-11-12T01:08:00.002-08:002014-08-11T03:09:24.606-07:00Livre SSIS 2012 paruJe fais rarement de la pub sur ce blog, seulement pour les éléments de qualité. J'en profite donc pour vous signaler la parution du livre <b>SSIS 2012 : Mise en oeuvre d'un projet ETL avec SSIS</b> aux éditions ENI que deux collègues (François et Romuald que je remercie encore une fois) et moi même avons réalisé. Il est disponble <a href="http://www.editions-eni.fr/sql-server-integration-services-2012-mise-en-oeuvre-d-un-projet-etl-avec-ssis/.62711ae6d6cd14ff52adfe2a85131a8a.html">ici</a>.<br />
<br />
<img alt="SQL Server Integration Services 2012 - Mise en oeuvre d'un projet ETL avec SSIS, sqlserver , microsoft , décisionnel , BI , etl , bdd , sgbdd , flux , lot ssis , sql serveur" class="min" itemprop="image" src="http://www.editions-eni.fr/supports-de-formation-sql-server-integration-services-2012-mise-en-oeuvre-d-un-projet-etl-avec-ssis/.6bd221a3d2111769119227ca07305791.jpg" title="SQL Server Integration Services 2012 - Mise en oeuvre d'un projet ETL avec SSIS" /> <br />
<br />
J'espère qu'il comblera vos attentes. N'hésitez pas à nous faire un retour dessus car l'année prochaine, nous allons certainement remettre le couvert sur un autre sujet.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-58664808018032296002012-11-09T05:59:00.000-08:002012-11-09T06:01:36.688-08:00Journées SQL Server 2012<br />
Comme l'année précédente, deux journées sont consacrées à SQL Server. L'objectif sera de présenter des nouveautés, des retours d'expériences et des éléments méconnus de la version 2012. Elles se dérouleront les 10 et 11 décembre, au Centre de Conférences Microsoft, 39 quai du Président Roosevelt à Issy-Les-Moulineaux.<b> </b><br />
<br />
<br />
<br />
<img height="112" src="http://guss.fr/Portals/0/Fichiers/JSS2012/jss2012-full-header3.png" width="640" /><br />
<br />
<br />
Pour ma part, nous préparons avec Tarik Broumi et David Tang une session autour des stratégies de processing que je présenterai avec ce dernier.<br />
Retrouvez toutes les informations ici: <a href="http://jss2012.fr/">http://jss2012.fr/ </a>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-39715105819570137022012-11-09T05:41:00.001-08:002012-11-09T05:51:07.580-08:00Web Service RS : modifier des propriétés de rapports<span lang="FR" style="mso-ansi-language: FR;">A toujours faire des billets qui
expliquent comment faire en sorte que les choses fonctionnent, j’ai envie d'en
faire un pour expliquer comment elles ne fonctionnent pas : ça changera.
Récemment, chez mon client préféré du moment, nous nous sommes aperçus que le
format appliqué aux données dans nos rapports RS n'était pas le bon (date et
chiffre au format anglais entre autre). Du coup, je décide de modifier les
paramètres de région du serveur (mode bourrin) : surprise, ça ne fonctionne
pas. J'ai tout essayé (enfin je crois) et je ne comprends pas pourquoi ça ne
passe pas. Je ferai un autre billet sur ce point plus tard.</span><br />
<span lang="FR" style="mso-ansi-language: FR;"></span><br />
<a name='more'></a><br />
<span lang="FR" style="mso-ansi-language: FR;">Il reste alors une solution :
modifier la propriété Language de mes rapports. Problème, il y en a 800
éparpillés dans toute une arborescence bien complexe. Un ajout en masse de la
balise Language dans le code XML du rapport ne pose pas de soucis, mais le
déploiement sera fastidieux.</span><br />
<span lang="FR" style="mso-ansi-language: FR;">Du coup, sur les conseils
éclairés d’un collègue (François pour ne pas le nommer) : on peut faire un
truc sale qui consiste à modifier les paramètres du rapport à son lancement (en
gros, écrire dans le XML). Chose facilité par le fait que l’exécution de ces
800 rapports est géré via du C#. Cool, une grosse partie du boulot est
fait : on va utiliser les classes et méthodes du WSDL référencé dans le
projet pour l’exécution des rapports. Ah, premier soucis, on utilise le Web
Service ReportService2005 pour lequel je ne trouve pas de méthode de
modification des paramètres d’un rapport. Un petit tour sur la MSDN (<a href="http://msdn.microsoft.com/en-us/library/ms155398.aspx">http://msdn.microsoft.com/en-us/library/ms155398.aspx</a>
et au passage il y a une erreur dedans, ce n’est pas le full path qui est
nécessaire pour leurs méthodes, juste l’arborescence RS jusqu’au rapport) pour
s’apercevoir qu’en fait, il existe trois Web Service différents. Super pratique
d’en faire autant quand même !! Donc, celui qui permet de tout faire, sauf
de l’exécution de rapport c’est ReportService2010. Je vous passe les classes et
méthodes pour ne retenir que SetProperties() de ReportingService2010. On se
fait une petite méthode de ce type : </span><br />
<br />
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="color: blue; font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;">private</span><span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"> <span style="color: blue;">void</span> ModifyProperty (<span style="color: blue;">string</span>
propertyName, <span style="color: blue;">string</span> propertyValue, <span style="color: blue;">string</span> reportPath)</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span>{</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span><span style="color: #2b91af;">Property</span>[]
props=<span style="color: blue;">new</span> <span style="color: #2b91af;">Property</span>[1];</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span><span style="color: #2b91af;">Property</span>
setProp=<span style="color: blue;">new</span> <span style="color: #2b91af;">Property</span>();</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span>setProp.Name=propertyName;</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span>setProp.Value=propertyValue;</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; mso-layout-grid-align: none; text-autospace: none;">
<span style="font-family: "Courier New"; font-size: 10.0pt; mso-no-proof: yes;"><span style="mso-spacerun: yes;"> </span></span><span lang="FR" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: FR; mso-no-proof: yes;">props[0]=setProp;</span></div>
<div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in; margin-left: .5in; margin-right: 0in; margin-top: 0in; mso-layout-grid-align: none; text-autospace: none; text-indent: .5in;">
<span lang="FR" style="font-family: "Courier New"; font-size: 10.0pt; mso-ansi-language: FR; mso-no-proof: yes;">myReportingService2010.SetProperties(reportPath,
props)</span></div>
<span lang="FR" style="mso-ansi-language: FR;"><span style="mso-spacerun: yes;"> </span>}</span><br />
<br />
<div class="MsoNormal">
<span lang="FR" style="mso-ansi-language: FR;">On exécute et… on se rend compte que la propriété
Language est Read-only. </span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<i><span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 107%; mso-fareast-font-family: "Times New Roman";">System.Web.Services.Protocols.SoapException:
The property 'Language' is read-only and cannot be modified or deleted.</span></i></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="FR" style="mso-ansi-language: FR;">Pourquoi ? Bonne question, je n’ai pas trouvé de
documentation, donc si vous en avez, je suis preneur. En tous cas, les prochains qui tenteront le coup
sont maintenant prévenus (je vous rassure quand même elles ne sont pas toutes inaccessibles).</span></div>
<br />Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-28855977045448487042012-04-17T06:59:00.001-07:002012-04-17T07:00:28.086-07:00NT AUTHORITY\SYSTEM n'est plus sysadmin sur 2012Dans nos tests de compatibilité sur 2012 (typiquement des migrations d'applications) nous nous sommes rendus compte que le login NT AUTHORITY\SYSTEM au niveau de l'instance n'est plus sysadmin sur SQL Server 2012 (c'était encore le cas en 2008 R2). Ce qui pose des problèmes quand, par exemple, vous avec un service Windows tournant avec le compte système local qui tente de piloter des bases de données pour votre application. On passe donc quelques temps à chercher pourquoi nous n'avons pas les droits sur Master afin de pouvoir créer une base par exemple.<br />
La préconisation : ne pas faire tourner ces applications avec le compte système local et utiliser des comptes de domaine si possible. Dans tous les cas, on évite de mettre ce compte système local sysadmin des bases de l'instance SQL.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-29579210151776082722012-02-21T06:29:00.000-08:002012-02-21T06:43:00.387-08:00PowerShell, c'est la vie!Commes mes fans se sont plaints <strike> hier</strike> il y a peu du manque d'activité sur ce blog, voici un petit post pour les réconforter (si je n'ai rien publié depuis, c'est parce que je suis sur l'écriture d'un livre sur SSIS et que je n'ai pas grand chose de nouveau à dire : on se cherche des excuses comme on peut).<br />
<br />
J'ai dû mettre en place <strike>aujourd'hui</strike> il y a peu la création automatique de partition sur SSAS. Ce n'est pas la première fois que je fais ça mais ici, la manière est bien différente car le contexte le requérait. D'habitude, la création de ces partitions s'inscrit dans un process global de mise à jour d'une partie du SID (ETL, DWH, etc...) : le tout est géré par un service Windows custom. Dans ce cas précis, l'AMO est idéal.<br />
<a name='more'></a><br />Dans le cas du jour, la création de partition est décoréllée de tout cela. Elle doit avoir lieu en fin d'année, vers le mois de Novembre afin d'anticiper l'arrivée des chiffres de l'année suivante. Bref, je me retrouve avec les méthodes que je connais :<br />
- du XMLA<br />
- de l'AMO<br />
- un lot SSIS<br />
<br />
Pour le XMLA, ça ne me convient pas car je vais avoir des expressions conditionnelles dans mon code.<br />
L'AMO, c'est bien, mais super lourd pour le déploiement. C'est sortir l'artillerie pour juste créer des partitions : à mon avis une perte de temps.<br />
Le lots SSIS avec un component script : la méthode la plus abordable à mon avis, mais chez le client en question, les normes de développement des lots sont lourdes et je ne me voyais pas passer ma journée à lire les docs pour coller à leurs spécifications juste pour un dtsx.<br />
<br />
Je n'ai pas envie de choisir entre ces méthodes en fonction de leurs inconvénients. Du coup, j'ai opté pour Powershell. C'est la première fois que je fais quelque chose de concret avec et je dois dire que c'est super agréable. On peut presque tout faire comme en AMO mais dans un fichier de script basique.<br />
<br />
L'exemple ci dessous permet de créer des partitions automatiquement pour tous les groupes de mesures en fonction de certains prédicats :<br />
- le partitionnement se fait sur l'année<br />
- le nommage des partitions est pertinent (le nom contient à minima l'année, idéalement à la fin du nom de la partition)<br />
- le formatage de la clé de temps est intelligent (20110101 au hasard)<br />
- une partition a été initialement définie dans le groupe de mesure afin de se baser dessus pour créer celles jusqu'à l'année en cours<br />
<br />
<br />
$serverName = "MonServeur\MonInstance"<br />
$dbName = "Adventure Works"<br />
$cubeName = "Adventure Works"<br />
$yearTarget=2013<br />
<br />
[System.Reflection.Assembly]::LoadwithpartialName("Microsoft.AnalysisServices") > $null<br />
$svr = New-Object Microsoft.AnalysisServices.Server<br />
$svr.Connect($serverName)<br />
$cub = $svr.Databases.Item($dbNamed).Cubes.FindByName($cubeName)<br />
#on parcourt les groupes de mesures<br />
foreach ($mg in $cub.MeasureGroups)<br />
{<br />
$part=$mg.Partitions<br />
#le nommage des partitions est MonGroupeDeMesure2012. Les partitions étant créées dans l'ordre <br />
chronologique, on ne récupère l'année que dans le nom de la dernière<br />
$yearInit= [int] ( $part[$part.Count-1].name.substring($part[$part.Count-1].name.length-4, 4))+1<br />
<br />
while($yearInit -le $yearTarget)<br />
{<br />
#on définit la requête source de la partition<br />
$query="SELECT MesColonnes FROM MaTable WHERE MaDateKey BETWEEN " + ([string]$yearInit)+"0101 AND <br />
"+([string]$yearInit)+"1231"<br />
#le slice correspondant<br />
$slice="[DimTime].[Calendar Hierarchy].[Year].&["+([string]$yearInit)+"]"<br />
#on ajoute la partition à la définition de mon cube<br />
$partadd=$mg.Partitions.add($mg.name+ " " + $yearInit)<br />
$partadd.Slice=$slice<br />
#j'instancie un objet de type QueryBinding pour la définition de la source : bien faire attention dans le cas où la base AS possède plusieurs DataSource de choisir la bonne dans la collection<br />
$partadd.Source= New-Object Microsoft.AnalysisServices.QueryBinding ($svr.Databases.Item<br />
($sourceDB).DataSources[0].ID ,$query)<br />
<br />
#ne pas oublier cette commande qui permet de valider les changements dans la structure, c'est une sorte <br />
de commit<br />
$partadd.Update()<br />
$partadd.Process()<br />
$yearInit++<br />
}<br />
}<br />
<br />
<br />
Ce code n'a pas de prétention particulière, c'est juste pour donner une base de syntaxe et vous convaincre que le PowerShell, c'est la vie.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com4tag:blogger.com,1999:blog-3892348099407749444.post-75368988016871537632011-11-14T08:09:00.000-08:002011-11-14T08:09:10.197-08:00Bug de traduction dans AS lors de la modification des types des attributsNous venons juste de découvrir un bug marrant dans les traductions de SSAS. Enfin, marrant parce que de prime abord on ne voit pas d’où ça vient, mais qui fait tout de même perdre quelques heures de recherche.<br />
<br />
Nous ne comprenions pas pourquoi, lors du procesing de notre dimension temps nous avions ce message d'erreur :<br />
<br />
<em><span lang="EN-US" style="mso-ansi-language: EN-US;">Errors in the back-end database access module. The size specified for a binding was too small, resulting in one or more column values being truncated. Errors in the OLAP storage engine: An error occurred while the 'Fiscal Quarter' attribute of the 'Time' dimension from the MyCube' database.</span></em><span lang="EN-US" style="mso-ansi-language: EN-US;"><o:p></o:p></span><br />
<br />
Généralement, ce message survient lorsque le dimensionnement des types de nos attributs ne correspond pas à celui des colonnes de la base de données source. Après avoir vérifié plusieurs fois et sur tous les attributs de notre dimension, il en résulte que tout est bien fait. Donc après avoir injustement accusé un de mes collègues, l'attribut en question est supprimé, puis recrée. Oh miracle, le problème de processing disparaît. Bref, impossible de savoir d'où cela vient.<br />
<br />
A mes yeux, il n'y a plus qu'une solution pour trouver la source du problème : faire un différentiel du XML entre les deux versions des dimensions. En faisant cela, on se rend compte que la traduction associé à l'attribut Fiscal Quarter possède le bon DataType, mais pas le bon DataSize.<br />
<br />
<b style="mso-bidi-font-weight: normal;">Conclusion</b> : cela vient du fait que le type de l'attribut a été modifié après la mise en place de la traduction. Ce procédé n'entraîne donc pas une mise à jour automatique des objets associés (tels que ceux de la traduction). La seule possibilité pour contourner le problème est de supprimer puis recréer la traduction pour l'attribut. Pas cool, sauf si vous connaissez une solution plus simple.<br />
<br />
<div class="MsoNormal" style="margin: 0cm 0cm 10pt;"><br />
</div>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-43251358136536526202011-10-11T02:09:00.000-07:002011-10-11T02:19:44.188-07:00Comportement du Many to Many avec plusieurs dimensions de jointureChez nos clients préférés, nous tombons bien souvent sur une modélisation un peu bizarre d'un cube AS. Bien sûre, il y a toujours une justification à cela car cette modélisation a été mise en place pour répondre à un besoin bien précis.<br />
Voici ladite modélisation (ça sera notre cas n°1) :<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHboEOeFXXLuF_r9PS1ehKebQgcH18lNsz6y-v8Ct3FVt689aBXJkRM7cPHoOV9kZfEDvHMjJsokbm9OZf6UN4KQTMQ8JkNSj5ArI9hh3N69YEM-TDj7QEhGfXUuQqNYfFGolzdApBbQ/s1600/Image1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHboEOeFXXLuF_r9PS1ehKebQgcH18lNsz6y-v8Ct3FVt689aBXJkRM7cPHoOV9kZfEDvHMjJsokbm9OZf6UN4KQTMQ8JkNSj5ArI9hh3N69YEM-TDj7QEhGfXUuQqNYfFGolzdApBbQ/s1600/Image1.png" /></a><br />
<br />
<a name='more'></a><br />
<br />
Un acheteur (DimAcheteur) se charge de l'approvisionnement aurpès des fournisseurs (FaitCommandeFournisseur). Les acheteurs sont associés à des groupes (DimGroupe) et un acheteur peut appartenir à plusieurs groupes, d'où la présence de la table de fait FaitGroupeAcheteur qui va permettre de faire le lien entre mes acheteurs et mes groupes via un Many-to-Many. De cette manière, on pourra faire une analyse des quantités commandées par groupe d'acheteur par exemple. Jusqu'ici, une Many-to-Many classique :<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP4WZz1RzVtJr3Ox5xDRtqtbrEpb_-j5O3GemqPxEq_E-L4f0wPAveKKYPb_2tkrZ5AR6m1jRMuq2O1r_2bL48eE5obD09zUMc6snY41h2wvmBrBF7QnPqA37yRMJ5EkcsMkqlpjjbxA/s1600/Image3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP4WZz1RzVtJr3Ox5xDRtqtbrEpb_-j5O3GemqPxEq_E-L4f0wPAveKKYPb_2tkrZ5AR6m1jRMuq2O1r_2bL48eE5obD09zUMc6snY41h2wvmBrBF7QnPqA37yRMJ5EkcsMkqlpjjbxA/s1600/Image3.png" /></a></div><br />
<br />
<br />
L'élément perturbateur, c'est la notion de responsable (DimResponsable). Un responsable, c'est un acheteur particulier, qui est responsable d'un groupe d'acheteur. On se dit tout de suite que nous devrions avoir une Parent-Child sur notre dimension DimAcheteur afin de créer cette relation hiérarchique ou a minima, que l'association avec FaitCommandeFournisseur générera des role playing dimension. Ici, rien de cela, la modélisation proposée sera la suivante (cas n°2) :<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggco0qfZlNzCF2yNPAft4LySjFssOhGPpY_jWl2DDZrHMG0tqHJ4R8o6dcYFg2Bdk3WW_kUlNF42ThJh_rLgQPrba7XhWNxX7Gq4asZMSO0JrghkUqw7P8vR2GQsyMShWLI7KOT9u8Qg/s1600/Image2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggco0qfZlNzCF2yNPAft4LySjFssOhGPpY_jWl2DDZrHMG0tqHJ4R8o6dcYFg2Bdk3WW_kUlNF42ThJh_rLgQPrba7XhWNxX7Gq4asZMSO0JrghkUqw7P8vR2GQsyMShWLI7KOT9u8Qg/s1600/Image2.png" /></a></div><br />
<br />
Bien évidemment, avant de se soucier de notre Many-to-Many, il y a clairement un problème de conception de notre DimAcheteur/DimResponsable. Mais imaginons que les changements ne peuvent être apportés tout de suite (trop d'impact, pas assez de temps, release de reporting qui approche, pression des utilisateurs pour avoir les groupes pour les repsonsables et les acheteurs...). Donc passons afin de nous attarder sur la tentative d'association de tous ces objets.<br />
Le but est toujours d'avoir la possibilité d'aggréger nos données fournisseurs en fonction du groupe d'acheteur. On pense donc à créer une relation de type Many-to-Many en plus de celle présente à la base. On obtiendra quelque chose de la sorte :<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWqyhZliijjWNWl4pLoMWaqawOB64rgOm6tBCWAh47JyfhuzZXqv9oY8akcgmlT0lD5JrgBgHTLwRGi_EUHLNXppGTqmTa-EQBEMDZ5CEQHMyxZYpTAuaedBPgcssRi00kE7f5sSEcog/s1600/Image4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWqyhZliijjWNWl4pLoMWaqawOB64rgOm6tBCWAh47JyfhuzZXqv9oY8akcgmlT0lD5JrgBgHTLwRGi_EUHLNXppGTqmTa-EQBEMDZ5CEQHMyxZYpTAuaedBPgcssRi00kE7f5sSEcog/s1600/Image4.png" /></a><br />
<br />
Et là on se dit : "Super, étant donné que mes reponsables sont aussi des acheteurs, mes clés vont correspondre avec ma table de fait intermédiaire". C'est vrai, mais le processing ne passera pas et les résultats de vos requêtes seront fausses. Pourquoi? Pour le premier point, étant donné que DimResponsable est un sous ensemble de DimAcheteur, il y a de grandes chances d'avoir des KeyErrors (dans le sens tous les acheteurs ne sont pas responsables). Donc soit on complète DimResponsable avec les lignes manquantes, soit on positionne le Key Not Found sur Ignore Error pendant le processing. Toujours dans un soucis de delivery, on préférera la seconde solution (bien évidemment, les deux propositions sont inacceptables en production, j'espère que vous l'aurez remarqué, c'est juste pour l'exemple). En ce qui concerne le second point, il faut revenir à la définition de ce qu'est une Many-to-Many.<br />
Une Many-to-Many va chercher à associer des tables de faits entre elles. Pour cela, AS utilisera une dimension commune à ces deux tables : c'est pour cela que dans le titre je parle de dimension de jointure. Dans notre premier cas qui fonctionne, c'est DimAcheteur qui sera utilisée.<br />
Mais dans le cas ou deux dimensions sont communes, comme dans l'exemple ci-dessus, laquelle sera choisie? DimAcheteur ou DimResponsable? Et bien ça depend du type de dimension : pour en savoir plus, je vous renvoie au Many-to-Many Revolution de Marco Russo (disponible ici). Ici, les deux seront utilisées (elles possèdent le même type d'association avec notre table de fait intermédiaire et la même granularité).<br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div>Que ce passe t-il quand je vais vouloir requêter mon groupe de mesure avec ma dimension DimGroupe? <br />
Soit la requête suivante :<br />
<br />
<span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">SELECT</span></span><span style="font-size: x-small;">[Measures].[Quantite Commandee] </span><span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">ON</span></span><span style="font-size: x-small;"> 0,</span><br />
<span style="font-size: x-small;"></span><span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">NON </span></span><span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">EMPTY</span></span><span style="font-size: x-small;"> [DimGroupe].[Groupe].[Groupe]*[DimAcheteur].[Acheteur].[Acheteur] </span><span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">ON</span></span><span style="font-size: x-small;"> 1</span><br />
<span style="font-size: x-small;"></span><span style="color: blue; font-size: x-small;"><span style="color: blue; font-size: x-small;">FROM </span></span><span style="font-size: x-small;">[Cube]</span><br />
<br />
SSAS va créer deux sous-cubes : un premier pour faire les lookups sur le groupe de mesure FaitGroupeAcheteur et un second pour aller chercher les données fournisseur (bien entendu, le lookup est la première opération réalisée). Dans le premier sous-cube, nous allons avoir trois colonnes : l'AcheteurID, le ResponsableID et le GroupID. Dans le second, ce que je projette : ici, l'AcheteurID et le GroupeID. Suite à cela, une comparaison sera faite entre les colonnes du premier et du second sous-cube. C'est à ce moment que quelque chose cloche, car AS va faire ces correspondances pour toutes les dimensions associées au groupe de mesure factless, donc DimAcheteur et DimResponsable. Du coup, nous nous retrouverons seulement avec les lignes de valeurs pour lesquelles le responsable et l'acheteur pour une commande fournisseur sont les mêmes. Les agrégations par groupe d'acheteur seront fausses car plusieurs valeurs de la mesure sont omises. On le voit bien dans ce profiler :<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglB8oh2U_L7WN1Ad2y8LX1chC9lUljh7mp4OljxW9FSYkR2vHFgarloNPM4eLheV3GmCPHlbnwynNsLuItBLbBOG5FzwnIlTbYILedxhNuH-ldaKE6D-dfRiPR4-1z8GOxJh2HkpmpPw/s1600/Sans+titre2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglB8oh2U_L7WN1Ad2y8LX1chC9lUljh7mp4OljxW9FSYkR2vHFgarloNPM4eLheV3GmCPHlbnwynNsLuItBLbBOG5FzwnIlTbYILedxhNuH-ldaKE6D-dfRiPR4-1z8GOxJh2HkpmpPw/s640/Sans+titre2.png" width="640" /></a></div><br />
En rouge, c'est la génération de mon sous-cube de Lookup, en bleu, la restitution de mes résultats. Pour la partie rouge, on voit que toutes mes dimensions attachées à mon groupe de mesure FaitGroupeAcheteur sont utilisées (1,1,1).<br />
<br />
Bref, c'était juste une illustration de ce qu'il ne faut pas faire et du pourquoi ça ne fonctionne pas. J'ai bien tenté de trouver un cas plus concret d'utilisation d'un Many-to-Many avec plusieurs dimension de jointure, mais sans succès.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com3tag:blogger.com,1999:blog-3892348099407749444.post-55714131569941266922011-06-14T08:23:00.000-07:002011-06-14T08:28:34.092-07:00Un nouveau must read sur ASJe n'ai pas pour habitude de le faire, mais j'annonce la publication d'un nouveau livre blanc : <a href="http://msdn.microsoft.com/en-us/library/hh226085.aspx">AS Operations Guide</a><br />
J'étais justement en train d'écrire un article assez détaillé qui résume la configuration à apporter à AS dans un environnement gros serveurs et multi-users, ce que je fais depuis un an chez mon client. C'est plus la peine maintenant, les informations se trouvent dans ce document.<br />
C'est un peu aussi pour me justifier du laps de temps entre maintenant et mon dernier post, je l'admets. Mais des documents de cette qualité vous enlève toute volonté d'en écrire pour le moment (je l'avoue, c'était un objectif :) )., surtout quand on voit la liste des auteurs.<br />
Bravo à eux.Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-69594578680135924892011-02-22T04:36:00.000-08:002011-02-23T02:06:38.499-08:00Attach/Detach manuel sur SSAS 2005Le procédé de mise en ligne/mise hors ligne ou Attach/Detach d'une base (bien pratique quelque fois) est une feature apparue à partir de 2008.<br />
Forcément en 2005, gros soucis pour réaliser cette opération, d'où mon problème du jour : la réinstallation d'une instance AS 2005 dont seuls les disques de données de l'ancienne instance ont été conservés (avec les répertoire ".db", c'est déjà ça) : bien entendu, on veut récupérer ces bases dont on ne dispose pas de backups (seulement les répertoires contenant les data file).<br />
<br />
Si vous gérez vos instances 2005 avec SSMS 2008, effectivement, dans le menu contextuel il y a bien possibilité de faire un Detach de votre base : autant vous dire tout de suite que ça ne fonctionne pas.<br />
<br />
Donc deux solutions :<br />
<ul><li>Soit vous modifiez dans le fichier de configuration de votre instance AS la propriété Datadir en renseignant le chemin du répertoire qui contient vos anciennes données, puis redémarrage de l'instance pour prendre en compte cette modification, puis backup des bases, puis re-changement du Datadir avec le chemin du répertoire de données initial, puis re-redémarrage de l'instance et enfin un Restore des backups nouvellement créés. Méthode la plus propre, mais lourde, surtout si vous avez 20 bases à sauvegarder puis à remonter.</li>
<li>Ou L'AUTRE méthode, un peu plus brutale mais qui permet de gagner du temps : un copier-coller des anciens répertoires ".db", des fichiers XML ".db.xml", du master.vmp et du CryptKey.bin dans votre répertoire de données actuel, un redémarrage de l'instance et le tour est joué. Bien entendu, ceci fonctionne avec une instance "à vide", sans base de données présente au préalable. Sinon, elle seront supprimées au redémarrage de l'instance car non référencées dans le nouveau (ancien) fichier master.vmp.</li>
</ul>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com2tag:blogger.com,1999:blog-3892348099407749444.post-22895606181031716102010-12-17T05:36:00.000-08:002011-01-05T00:15:15.688-08:00Changer la base SSAS par défaut<div class="bText" style="text-align: justify;">Voici le problème auquel j’ai été confronté : des utilisateurs requêtant AS via Excel, disposent d’une chaîne de connexion sur cette instance AS sans avoir précisé la base de données (mot clé <b>Catalog absent de la connection string</b> : à éviter). Après quelques heures d’utilisation, ils se rendent compte que leurs chiffres ne sont pas bons et pour cause. La veille, de nouvelles versions de leurs bases de données avaient été livrées dans un ordre qui, je ne sais pas pourquoi, a fait changer la <b>base dite par défaut</b>. Du coup, leurs requêtes attaquaient la mauvaise base de données (le Catalog n’étant pas précisé, la base par défaut est utilisée).<br />
<br />
<b>Ma question</b> : comment déterminer la base qui est utilisée par défaut par notre instance ? Sur SQL, une requête du type <i>Exec sp_defaultdb @loginame='monLogin', @defdb='maBase'</i> permet de modifier ce paramètre facilement. Je n’ai pas trouvé l’équivalent sur SSAS, en tous les cas pas en 2005 (je n’ai pas regardé pour 2008 et 2008R2).<br />
<br />
<div class="bMore"><a href="http://www.blogger.com/post-edit.g?blogID=3892348099407749444&postID=2289560618103171610" id="more9588" name="more9588"></a></div>En fouillant un peu dans les fichiers xml d’AS, j’ai trouvé la solution. Chaque base de données possède un fichier qualifié de « référence » pour l’ensemble de l’instance. Le nom de ce fichier est de la forme NomDeMaBaseAS.db.xml. Il contient entre autre le nom et l’ID de la base, les paramètres de traduction, les annotations, etc. Il contient également une propriété qui se nomme <b>Ordinal</b>, et qui précise justement la place de la base de données parmi les autres via un numéro. Si l’ordinal est 0, cette base sera la première, 1 la seconde et ainsi de suite. La base possédant le plus petit ordinal sera celle qui sera considérée comme étant celle par défaut. Il suffit donc de s’arranger pour que la base que vous souhaitez définir comme étant celle par défaut possède le plus petit ordinal. Fastidieux quand il y a beaucoup de base de données (une petite astuce pour éviter d'avoir à parcourir tous les fichiers pour trouver le plus petit ordinal consiste à donner une valeur négative à l'ordinal de la base par défaut : ça marche). C’est pour cela que si jamais vous connaissez une autre solution, je suis preneur. Autre précision, je ne sais pas comment sont déterminés ces ordinaux au moment des déploiements.</div>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com2tag:blogger.com,1999:blog-3892348099407749444.post-90024896482002576482010-12-03T00:13:00.000-08:002011-10-11T02:19:32.749-07:00Passage du MCT<div class="bText" style="text-align: justify;">Aller hop, un autre sujet que SSAS pour changer. Je viens de passer avec succès ma certification MCT (Microsoft Certified Trainer). Pour info, cette certification est indispensable pour pouvoir dispenser des cours officiels Microsoft (ça tombe bien, j’avais ambitionné de devenir professeur de physique-chimie à la sortie du Bac). Bien entendu, la partie qui va me concerner, c'est la BI (il faut d'ailleurs être MCITP avant d'être MCT, pour SQL Server 2008, ce sont les certifications 70-448 et 70-452 pour la BI).<br />
L'examen se compose de deux parties. La première consiste en un QCM qui propose 10 situations conflictuelles à gérer, auxquelles il faut trouver le bon comportement à adopter. Par exemple, une situation du type : un étudiant ne se sent pas concerné par ce que vous raconter, comment le réintégrer au groupe? <br />
La seconde partie est une présentation d’un sujet technique en 15 minutes. Le sujet sur lequel je suis tombé est « la présentation du panneau de configuration ». Autant dire que vous ne serez pas évalués sur vos connaissances, mais bel et bien sur la forme de votre prestation orale.<br />
<br />
Les points clés pour une certification réussie :<br />
<ul><li>Une bonne présentation orale (prestance, voix, ton, mouvement dans la salle, etc.)</li>
<li>Un brin de diplomatie dans la gestion des conflits (pour le QCM)</li>
<li>Un support de formation propre (Power Point, à préparer par vos soins avant le passage de la certification)</li>
<li>Une attention particulière à vos étudiants (est-ce qu’ils suivent, est ce qu’ils ont tout compris)</li>
<li>Interaction avec votre auditoire</li>
</ul>Si certains d’entre vous se sentent l’âme d’un formateur…</div>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0tag:blogger.com,1999:blog-3892348099407749444.post-59053082646589155732010-11-16T00:18:00.000-08:002011-01-05T04:48:17.920-08:00Extraire votre script XMLA de création de base SSAS en AMO<div align="left" class="bText"><div style="text-align: justify;"></div><div style="text-align: justify;">On m’a demandé il n’y a pas longtemps s’il était possible de récupérer le script de création d’une base AS. Bien entendu, Managment Studio permet de le faire simplement. Mais dans le cas qui nous intéresse, le script de création devait être récupéré lors des backups, donc de manière automatisée.<br />
Pour cela, il y a des classes en AMO qui permettent de le faire assez facilement. Un code du genre de celui-ci-dessous vous en donne un exemple :<br />
<br />
<a name='more'></a></div><div class="bMore"><a href="http://www.blogger.com/post-edit.g?blogID=3892348099407749444&postID=5905308264658915573" id="more9495" name="more9495"></a></div><code><br />
srv.Connect("MonServeur\MonInstanceAS");<br />
Database db = srv.Databases.FindByName("MaBaseAS");<br />
Scripter scripter = new Scripter();<br />
System.Xml.XmlTextWriter xmlWriter = new System.Xml.XmlTextWriter("C:\\MonScript.xml", Encoding.UTF8); <br />
Scripter.WriteCreate (xmlWriter ,srv,db,true, true);<br />
xmlWriter.Close(); </code><br />
<code><br />
</code><br />
Les deux derniers paramètres de la méthode WriteCreate de votre Scripter sont :<br />
<ul><li><b>fullExpanded :</b> </li>
</ul> - false :le script ne contriendra que la création de la base<br />
- true : il incluera tous les objets de votre base (dimensions, cubes, etc.) <br />
<ol></ol><ul><li><b>allowOverwrite :</b></li>
</ul><ol></ol> - false : lors de l’exécution du script, si la base existe, elle ne sera pas écrasée<br />
- true : c’est l’inverse<br />
<br />
<ul></ul><div style="text-align: justify;">L’objet Scripter possède bien d’autres méthodes que vous pouvez retrouver sur le net ou dans le livre MS SQL Server Analysis Services Unleashed.</div><div></div><div style="text-align: justify;">Si jamais il y en a qui aime se prendre la tête, vous pouvez aussi « parser » le résultat d’une requête XMLA comme DISCOVER_XML_METADATA qui contient lui aussi toute la description de votre base (je dis ça parce que c’est ce que je cherchais à faire au début).</div><br />
<u>Source</u> :<br />
MS SQL Server Analysis Services Unleashed (chapitre 34, p 694)</div>Patrice Harelhttp://www.blogger.com/profile/16287269246969578094noreply@blogger.com0