Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1338 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Gestion de la mémoire (résolu, merci !)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Gestion de la mémoire (résolu, merci !)

n°1977268
Fred999
Rabat-joie
Posté le 25-03-2010 à 14:06:32  profilanswer
 

M'sieurs-dames,
 
Préambule : pour simplifier la compréhension fonctionnelle, on dira que je gère un stock de bouteilles de vin :o
 
Le script en question consiste à générer un fichier XML à partir du résultat de procédures stockées (i.e. de tableaux). Le fichier comporte les informations relatives à différents crus de vin.
 
Pour cela, j'ai trois classes :  
 
- une première qui pilote tout le traitement
- une seconde qui crée un élément XML, va chercher récursivement ses enfants et, le cas échéant, va chercher des données en base
- une troisième qui va donc chercher des données en base
 
Après des tests de perfs, on arrive à une utilisation mémoire importante : 175 Mo, pour 400 crus de vin (le rapport RAM/nombre de crus répond à peu près à une droite selon le nombre de crus demandés : 1 cru => 350 Ko).
 
Cette utilisation ne pose pas de souci aux admins (vu qu'on a plusieurs Go), mais je ne suis pas à l'abri qu'un jour, le périmètre de crus soit beaucoup plus important, et là, si on atteint le Go, ça risque de beaucoup moins leur plaire.
 
D'où mon désir d'optimiser le truc. Pour cela, au lieu de faire directement un objet-arbre qui comporte les infos relatives aux N crus puis de générer le fichier, je désire faire N objets-arbres, générer le fichier à chaque fois, puis fusionner les fichiers après coup : ainsi, si je n'ai qu'un seul objet-arbre à la fois en mémoire, il prendra beaucoup moins de place.
 
Ca, c'est en théorie [:sadnoir]
 
En pratique, je me suis apercu que les objets ne se détruisaient qu'en toute fin de script : c'est sans doute un problème de référence croisée, ce que je peux comprendre. Mais j'ai également remarqué que l'utilisation mémoire restait constante lors de chaque appel au destructeur d'un objet (en traçant avec un memory_get_usage())... ce qui, à mon avis, n'est pas du tout normal.
 
Si vous avez des pistes... merci d'avance.


Message édité par Fred999 le 26-03-2010 à 18:36:10
mood
Publicité
Posté le 25-03-2010 à 14:06:32  profilanswer
 

n°1977271
FlorentG
Posté le 25-03-2010 à 14:12:41  profilanswer
 

Déjà utilise xdebug et la fonction xdebug_start_trace, pour logger chaque appel de fonction, et voir directement l'utilisation mémoire, histoire de vérifier qu'il n'y a pas de fonction qui leak à mort quelque part.

n°1977278
rufo
Pas me confondre avec Lycos!
Posté le 25-03-2010 à 14:28:05  profilanswer
 

Tu peux utiliser unset() dans tes scripts sur les objets à détruire. Après, il me semble que j'avais lu un truc au sujet de la désalloc de mémoire en php 6 dans le cas de réf croisées.
 
Après, faudrait peut-être revoir le processus de traitement et trouver un moyen plus adapté (par ex, utiliser un binaire en C qui assurait certains traitements lourds que PHP ne peut faire sans exploser la mémoire :/ J'ai déjà été amené à faire ça dans le cadre de calcul matriciel.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°1977280
FlorentG
Posté le 25-03-2010 à 14:29:09  profilanswer
 

Y'a aussi la manière dont est créé le fichier XML. Si c'est avec du DOM [:cerveau ouch]

n°1977286
Fred999
Rabat-joie
Posté le 25-03-2010 à 14:36:01  profilanswer
 

Merci pour vos réponses.
 
FlorentG ([:sadnoir]), xdebug a l'air bien intéressant, , et en plus il est déjà installé... par contre le site xdebug est bloqué par websense, OH OUI
 
rufi, j'utilise effectivement unset, de toute manière j'suis bien obligé sinon les variables ne seront relâchées qu'après l'exécution du script. Pour le C, c'est inenvisageable, vu que c'est hors de mes compétences :o

n°1977288
Fred999
Rabat-joie
Posté le 25-03-2010 à 14:40:35  profilanswer
 

(la log xdebug fait 240 Mo, c'est impossible à ouvrir oO)

 

... et c'est évidemment avec du DOM, mais ce n'est pas le plus coûteux : je ne me sers de DOM que pour la toute fin, lui passant un arbre déjà construit sous forme de tableau pour faire un save().

 

Comme vous l'imaginez, j'me suis retrouvé avec ce truc à faire et aucune piste de départ : il faut qu'on puisse sortir N données à partir de N procs et que le tout soit paramétrable via un client, sinon ce serait trop simple :o. J'ai donc créé de toutes pièces le modèle de données (Sybase) et l'interface client (en C# avec un autre collègue).


Message édité par Fred999 le 25-03-2010 à 14:41:02
n°1977291
rufo
Pas me confondre avec Lycos!
Posté le 25-03-2010 à 14:43:11  profilanswer
 

Si le C est pas à ta portée, regardes un autre langage compilé. Pour les traitement de gros volumes de données, PHP n'est pas adapté :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°1977293
Fred999
Rabat-joie
Posté le 25-03-2010 à 14:45:27  profilanswer
 

C'est imposé... je l'aurais bien fait en C#, amha beaucoup plus adapté, ou même en java, mais bon, j'suis presta hein, c'est pas comme si on m'écoutait quand je suggère quelque chose.


Message édité par Fred999 le 25-03-2010 à 14:45:54
n°1977295
FlorentG
Posté le 25-03-2010 à 14:48:45  profilanswer
 

On veut le code :o

n°1977305
Fred999
Rabat-joie
Posté le 25-03-2010 à 15:02:37  profilanswer
 

J'pense vraiment qu'il est trop long pour que vous vous embêtiez dessus :/

 

Pour résumer : la classe de pilotage appelle la classe élément avec l'identifiant 0 du schéma XML voulu (0 correspondant à la racine).

 

Dans la classe élément, on va regarder quel est l'élément enfant de l'élément en cours. Si cet élément est associé à des données, on regarde si on a déjà récupéré les données lui correspondant (à partir d'une ligne de commande SQL automatiquement générée). Si c'est le cas, soit c'est un élément qui se contente d'afficher une valeur (on la récupère), soit c'est un élément répété n fois (typiquement : un cru). Dans ce cas, on effectue une boucle sur tous les crus possibles, qui iront chercher leurs enfants (nom, millésime), etc, c'est du récursif, pas de surprise.

 

La classe données comprend un récapitulatif de toutes les exécutions SQL effectuées, ainsi que les données elles-mêmes (du coup, un parent repasse les données à son enfant et ainsi de suite, ce qui est clairement coûteux niveau mémoire, mais j'ai pas trouvé comment faire autrement : aucun changement si je tente d'utiliser & ).

 


C'est compliqué d'étudier xdebug, faudrait que je puisse tripoter un peu la configuration... mais thx.


Message édité par Fred999 le 25-03-2010 à 15:03:24
mood
Publicité
Posté le 25-03-2010 à 15:02:37  profilanswer
 

n°1977307
stealth35
Posté le 25-03-2010 à 15:04:46  profilanswer
 

Citation :

une seconde qui crée un élément XML, va chercher récursivement ses enfants


 
t'utilises xpath pour ca ?

n°1977309
Fred999
Rabat-joie
Posté le 25-03-2010 à 15:07:23  profilanswer
 

Non, du PHP simple : la classe dédiée au XML (DOM) ne sert qu'à la toute fin, pour générer le fichier à partir de l'arbre complet.

n°1977312
Fred999
Rabat-joie
Posté le 25-03-2010 à 15:10:31  profilanswer
 

D'après la trace, ce qui coûte hyper cher ce sont les multiples appels à la base : il faudrait que je charge le schéma au préalable... j'vais me lancer là-dedans, faut pas attendre de progrès avant demain midi :o

n°1977314
stealth35
Posté le 25-03-2010 à 15:12:05  profilanswer
 

tes données sont dans une base mysql ? si oui t'utilise PDO ?


Message édité par stealth35 le 25-03-2010 à 15:12:32
n°1977316
Fred999
Rabat-joie
Posté le 25-03-2010 à 15:15:54  profilanswer
 

Sybase, framework du client pour récupérer les données, chaque appel coûte un bras.

n°1977324
stealth35
Posté le 25-03-2010 à 15:22:21  profilanswer
 

Sybase avec PDO ca le fait, mais si ta pas le choix d'utiliser le framework, ca doit plus être ca qui coince

n°1977502
esox_ch
Posté le 25-03-2010 à 19:44:09  profilanswer
 

Hello,
 
Tes appels à la base sont optimisés ( requêtes préparées & co) ?
Ton schémas de base de donnée pareil ( index, ...) ?
Les config de ta bdd aussi?
 
Bref, c'es la requête SQL elle même qui te coûte cher, ou c'est ce que PHP en fait après?


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°1977810
Fred999
Rabat-joie
Posté le 26-03-2010 à 15:51:59  profilanswer
 

Salut et merci pour ta réponse,

 

Les requêtes sont générées à la volée ; pour leur exécution, je n'ai pas le choix de la méthode donc rien à creuser de ce côté. De toute manière, ça ne jouera pas sur la mémoire utilisée côté PHP.

 

Depuis hier, j'ai modifié l'algo pour charger le schéma au préalable, nettoyé toutes les variables et attributs facultatifs, et j'arrive à 1.5 Ko/tag dans le fichier XML final, pour environ 500 Ko par cru de vin.

 

PHP 5 passant par défaut les variables par référence, je pense effectuer le minimum de déclarations. Le souci est que, plus le périmètre augmente, plus on consomme, au début de manière exponentielle, puis la moyenne baisse... c'est louche :/

 

Voici les stats :

 

10 crus : 3.93 Mo pour 3265 tags en 15" soit 1.18 Ko/tag, 384 Ko/cru et 1.5 sec/cru
20 crus : 9.70 Mo pour 6435 tags en 37" soit 1.47 Ko/tag, 473.6 Ko/cru et 1.85 sec/cru
50 crus : 26.21 Mo pour 15841 tags en 2'15" soit 1.61 Ko/tag, 512 Ko/cru et 2.7 sec/cru
100 crus : 50.06 Mo pour 31700 tags en 6'30" soit 1.54 Ko/tag, 488.96 Ko/cru et 3.9 sec/cru

 

Le seul truc que je peux voir à partir de ces données est que plus on consomme, plus c'est lent.

 

Je vais fouiller du côté de l'optimisation des différentes boucles et fonctions de recherche.


Message édité par Fred999 le 26-03-2010 à 15:56:53
n°1977829
FlorentG
Posté le 26-03-2010 à 16:19:55  profilanswer
 

Là comme dit, le seul moyen de vraiment voir où le problème est, c'est d'utiliser xdebug :/ Et avec une trace pour 10 crus, ça ne fait pas un trop gros fichier ?

n°1977832
Fred999
Rabat-joie
Posté le 26-03-2010 à 16:23:59  profilanswer
 

Hum une paille, 119 Mo [:ddrs55]
 
Pour un cru; on a 15 Mo, c'est plus utilisable, allez on part à la mine :o

n°1977876
Fred999
Rabat-joie
Posté le 26-03-2010 à 18:35:03  profilanswer
 

Bon hey j'ai épluché le code, et ça a donné de bons résultats : en fouillant et optimisant les appels au framework, l'utilisation mémoire a baissé de 40%, par ricochet un post-traitement de récupération de données extrêmement coûteux (foreach imbriqués sur des array_keys) est passé à la trappe => résultat, un temps de traitement divisé par... 10 (j'ai été jusqu'à remplacer les array_push($tab, $elt); par $tab[] = $elt; [:pingouino])

 

Pour 400 crus soit 130K tags et un fichier en sortie de 4 Mo (ce qu'on aura en prod) :

 

Avant : 216 Mo en 1h38, soit 527 Ko/cru et 14 sec/cru
Après : 97.5 Mo en 9'11, soit 238 Ko/cru et 1.37 sec/cru

 

Maintenant, les chiffres sont complètement acceptables, au point qu'on pourra se servir de l'outil sur le site, à la demande (pour de petits périmètres, une dizaine par exemple).

 

Merci donc à tout le monde et surtout à florent, xdebug m'a permis de voir que les foreach imbriqués étaient vraiment hyper coûteux et de chercher à m'en débarrasser [:bien]

Message cité 1 fois
Message édité par Fred999 le 26-03-2010 à 18:35:50
n°1977881
Elmoricq
Modérateur
Posté le 26-03-2010 à 19:04:14  profilanswer
 

Juste pour ajout > si les requêtes à la DB prennent du temps, prends les plus consommatrice et exécute-les dans un isql avec un "set showplan on". Le but : éliminer les scan table, pour taper sur les index s'il y en a, ou en ajouter si besoin.
Ça change absolument tout sur les perfs.

Message cité 1 fois
Message édité par Elmoricq le 26-03-2010 à 19:05:47
n°1977937
esox_ch
Posté le 27-03-2010 à 10:52:18  profilanswer
 

Elmoricq a écrit :

Juste pour ajout > si les requêtes à la DB prennent du temps, prends les plus consommatrice et exécute-les dans un isql avec un "set showplan on". Le but : éliminer les scan table, pour taper sur les index s'il y en a, ou en ajouter si besoin.
Ça change absolument tout sur les perfs.


 
Salut,
Tu peux développer  ta réponse STP? J'ai jamais utilisé la technique dont tu parles (je ne suis même sûr de savoir comment faut la mettre en place) mais ça m'intéresse  [:kbchris]  


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°1977943
Fred999
Rabat-joie
Posté le 27-03-2010 à 11:33:56  profilanswer
 

Thx Elmoricq, ça je connais, effectivement ça aide bien sur certaines requêtes, là c'est du quasi-immédiat à chaque fois donc ça ne pêche pas, enfin je jetterai quand même un oeil. Au taf j'ai une toute vieille version d'isql récupérée il y a 10 ans sur un projet :o
 
esox_ch, c'est du spécifique Sybase, (peut-être que MS SQL Server le fait aussi ? vu les liens de parenté...)
 
set showplan on provoque l'affichage du plan d'exécution de ta requête lorsqu'elle est exécutée : tu vois alors si les index (et lesquels) sont utilisés, ou si tu fais le truc honni, un table scan.
 
Dans la même famille de commandes utiles, il y a set exec on/off pour justement ne pas provoquer l'exécution mais ne voir que le plan (ça s'utilise en couple avec la commande précédente), et set stats i/o (connais plus la syntaxe exacte), ça te donne une idée encore plus précise de la conso de ta requête.
 
Ca marche avec des procs ou des requêtes simples.

n°1977948
esox_ch
Posté le 27-03-2010 à 12:09:36  profilanswer
 

Ok merci :o


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°1977949
Elmoricq
Modérateur
Posté le 27-03-2010 à 12:10:40  profilanswer
 

Fred [:romf]

 

J'connaissais pas set stats, va falloir que j'y jette un oeil à l'occasion (les requêtes critiques on demande à nos DBAs de nous les optimiser :o)


Message édité par Elmoricq le 27-03-2010 à 12:11:31
n°1978405
FlorentG
Posté le 29-03-2010 à 14:43:30  profilanswer
 

Fred999 a écrit :

Merci donc à tout le monde et surtout à florent, xdebug m'a permis de voir que les foreach imbriqués étaient vraiment hyper coûteux et de chercher à m'en débarrasser [:bien]


[:romf]
 

Fred999 a écrit :

set showplan on provoque l'affichage du plan d'exécution de ta requête lorsqu'elle est exécutée : tu vois alors si les index (et lesquels) sont utilisés, ou si tu fais le truc honni, un table scan.


Pour ceux qui veulent faire pareil sous MySql, suffit de préfixer la requête par EXPLAIN

n°1978465
Fred999
Rabat-joie
Posté le 29-03-2010 à 16:10:07  profilanswer
 

Avec le soft que j'utilise, c'est simplissime, tu coches des cases dans une fenêtre d'options [:cosmoschtroumpf]

 

Pour les sybasiens, un c/c de l'aide sql server (compatible sybase) (pavé inside)

 

For more information about how SQL Server 6.5 affects existing database systems and for updated SQL Server 6.5 syntax, see SET Statement.
Sets SQL Server query-processing options for the duration of the user's work session, or for the duration of a running trigger or a stored procedure.
Syntax

 

SET {
{{{ANSI_NULL_DFLT_OFF | ANSI_NULL_DFLT_ON}
| ARITHABORT
| ARITHIGNORE
| FMTONLY
| FORCEPLAN
| IDENTITY_INSERT [database.[owner.]]tablename
| NOCOUNT
| NOEXEC
| OFFSETS {keyword_list}
| PARSEONLY
| PROCID
| QUOTED_IDENTIFIER
| SHOWPLAN
| STATISTICS IO
| STATISTICS TIME}
 {ON | OFF}}
| DATEFIRST number
| DATEFORMAT format
| DEADLOCKPRIORITY {LOW | NORMAL}
| LANGUAGE language
| ROWCOUNT number
| TEXTSIZE number
| TRANSACTION ISOLATION LEVEL {READ COMMITTED | READ
 UNCOMMITTED | REPEATABLE READ | SERIALIZABLE}}

 

where

 

ANSI_NULL_DFLT_OFF

 

Alters the session's behavior not to use ANSI compatibility for nullability. When this session option is turned on, it overrides the default database nullability configured by the sp_dboption system stored procedure. New columns defined without explicit nullability will be defined not to allow NULLs (as long as the underlying datatype is nullable). For more information on datatypes, see the Datatypes topic.

 

ANSI_NULL_DFLT_ON

 

Alters the sessions behavior to ANSI compatibility for nullability. When this session option is turned on, it overrides the default database nullability configured by the sp_dboption system stored procedure. New columns defined without explicit nullability will be defined to allow NULLs.

 

Note  ANSI_NULL_DFLT_ON and ANSI_NULL_DFLT_OFF are mutually exclusive options, yet both options exist to determine whether or not the database option should be overridden. When turned ON, each option forces the opposite option to OFF. Neither option, when set OFF, turns the opposite option ON. Instead, turning an option OFF only discontinues the current ON setting.

 

ARITHABORT

 

Terminates a query when an overflow or divide-by-zero error occurs during query execution. It is possible for rows in a results set to be returned prior to the overflow or divide-by-zero occurrence.

 

ARITHIGNORE

 

Returns NULL when an overflow or divide-by-zero error occurs during a query. No warning message is returned.

 

Note  If neither ARITHABORT nor ARITHIGNORE is set, SQL Server returns NULL and returns a warning message after the query is executed.

 

FMTONLY

 

Returns only metadata to the client. No rows will be processed or sent to the client as a result of the request when FMTONLY is turned ON.

 

FORCEPLAN

 

Makes the SQL Server optimizer process joins in the same order as tables appear in the FROM clause. FORCEPLAN essentially overrides the optimizer.

 

IDENTITY_INSERT [database.[owner.]]tablename

 

Specifies the database, owner and table in which explicit identity values can be inserted. Only one table per user can have the IDENTITY_INSERT option set. If the value inserted is larger than the current identity value for the table, SQL Server will automatically use the new inserted value as the current identity value. For details, see the IDENTITY property.

 

NOCOUNT

 

Turns off the message returned at the end of each statement that states how many rows were affected by the statement. The global variable @@ROWCOUNT is updated even when NOCOUNT is turned ON.
In SQL Server, SET NOCOUNT ON eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. For stored procedures that contain several statements that do not return much actual data, this can provide a significant performance boost because network traffic is greatly reduced.

 

NOEXEC

 

Compiles each query but does not execute it. NOEXEC is often used with SHOWPLAN. Once NOEXEC is turned on, no subsequent statements are executed (including other SET statements) until NOEXEC is turned OFF.
Statement processing consists of two phases, compilation and execution. NOEXEC stops the processing after compilation.

 

OFFSETS

 

Returns the keyword_list offset (position in relation to the beginning of the query) of specified keywords in SQL statements. The keyword_list is a list, separated with commas, that can include any of these SQL constructs: SELECT, FROM, ORDER, COMPUTE, TABLE, PROCEDURE, STATEMENT, PARAM, and EXECUTE.
The OFFSETS option is used only in a DB-Library application.

 

PARSEONLY

 

Checks the syntax of each query and returns any error messages without generating a sequence tree, compiling, or executing the query. Do not use PARSEONLY in a stored procedure or a trigger. PARSEONLY returns offsets if the OFFSETS option is ON and no errors occur.

 

PROCID

 

Returns the identification number of the stored procedure to DB-Library (not to the user) before sending rows generated by that stored procedure.

 

QUOTED_IDENTIFIER

 

Causes the current session to differentiate between single and double quotation marks when evaluating an expression. When QUOTED_IDENTIFIER is turned ON, strings with double quotation marks (" ) will not be evaluated or checked against keywords. For details, see the Identifiers topic.

 

SHOWPLAN

 

Generates a description of the processing plan for the query and immediately processes it unless NOEXEC is set. This option can indicate whether an index is being used to retrieve query results.

 

STATISTICS IO

 

Displays the number of scans, the number of logical reads (pages accessed in cache), and the number of physical reads (number of times the disk was accessed) for each table referenced in the statement.

 

STATISTICS TIME

 

Displays the time, in milliseconds, required to parse and compile each command and the time required to execute each step of the command.

 

DATEFIRST number

 

Sets the first weekday to a number from 1 through 7. The U.S. English default is 7 (Sunday).

 

DATEFORMAT format

 

Sets the order of the date parts (month/day/year) for entering datetime or smalldatetime data. Valid parameters include mdy, dmy, ymd, ydm, myd, and dym. The U.S. English default is mdy.

 

DEADLOCKPRIORITY {LOW | NORMAL}

 

Controls how this session reacts when in a deadlock situation. If set to LOW, this process will be the preferred victim of a deadlock situation. Use the NORMAL option to return the session to the default deadlock-handling method.

 

LANGUAGE language

 

Specifies the language in which system messages are displayed. The language must be available on the server. The default is us_english.

 

ROWCOUNT number

 

Causes SQL Server to stop processing the query after the specified number of rows are returned. To turn this option off (so that all rows are returned), use SET ROWCOUNT 0.

 

Note  Setting the ROWCOUNT option causes all Transact-SQL statements to stop processing when they have each affected number rows. This includes triggers and data modification statements such as INSERT, UPDATE, and DELETE as well as the filling of a keyset cursor at the specified number of rows. This option should be used with caution and primarily with the SELECT statement.

 

TEXTSIZE number

 

Specifies the size, in bytes, of text data to be returned with a SELECT statement. If you specify a TEXTSIZE of 0, the size is reset to the default (4K). Setting TEXTSIZE affects the global variable @@TEXTSIZE.
The DB-Library variable DBTEXTLIMIT also limits the size of text data returned with a SELECT statement. If DBTEXTLIMIT is set to a smaller size than TEXTSIZE, only the amount specified by DBTEXTLIMIT is returned. For more information, see Microsoft SQL Server Programming DB-Library for C.

 

TRANSACTION ISOLATION LEVEL

 

Controls the default transaction locking behavior for all SQL Server SELECT statements for this connection. Only one of the options can be set at a time, and it remains set for that connection unless it is explicitly changed. This becomes the default behavior unless an optimization option is specified at the table level in the FROM clause of your statement. For details, see the SELECT statement. To see what isolation level is currently set, use DBCC USEROPTIONS. For more information on DBCC, see the DBCC statement.

 

where

 

READ COMMITTED

 

Is the default mode for SQL Server. Setting this option returns transaction locking behavior to the SQL Server default, and you will not encounter "dirty reads." However, because shared locks do not exclusively hold records until the completion of a transaction, you might still encounter non-repeatable reads and phantom values later within your transaction.

 

READ UNCOMMITTED

 

Implements "dirty read," or isolation level 0 locking, which means that no shared locks are issued and no exclusive locks are honored. When this option is set, it is possible to read uncommitted data, have values change if reread in the same transaction, and have phantom values.

 

REPEATABLE READ | SERIALIZABLE

 

Are currently implemented identically. In some database systems, REPEATABLE READ means that "dirty reads" and non-repeatable reads are not possible but phantoms are possible. However, because REPEATABLE READ is a synonym for SERIALIZABLE in SQL Server's implementation, phantoms are not allowed when one of these is set. Because concurrency is lower, use these options only when necessary.
These options have the same effect as setting HOLDLOCK on all tables in all SELECT commands within a transaction.

 

Remarks

 

If you use the SET statement inside a trigger or a stored procedure, the option reverts to its former setting after the trigger or stored procedure is executed.
Options changed with the SET statement take effect at the end of the batch. You can combine SET statements and queries in the same batch, but the SET options won't apply to the queries in that batch.

 

Examples

 

A. SHOWPLAN

 

This example shows that setting the SHOWPLAN returns a description of the processing plan for each query prior to returning the results set. Notice that the SET option must be turned on prior to the execution of the SELECT statement.

 

SET SHOWPLAN ON
go
select * from publishers

 

go
STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Table Scan

 

pub_id pub_name                  city          state    country      
------ ------------------------- ------------- -------- ------------
0736   New Moon Books            Boston        MA       USA          
0877   Binnet & Hardley          Washington    DC       USA          
1389   Algodata Infosystems      Berkeley      CA       USA          
1622   Five Lakes Publishing     Chicago       IL       USA          
1756   Ramona Publishers         Dallas        TX       USA          
9901   GGG&G                     München       (null)   Germany      
9952   Scootney Books            New York      NY       USA          
9999   Lucerne Publishing        Paris         (null)   France      

 

(8 row(s) affected)

 

B. SHOWPLAN and NOEXEC

 

This example shows how the query plan can be viewed without returning the results.

 

SET SHOWPLAN ON
SET NOEXEC ON
go
SELECT * FROM publishers

 

go

 

STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Table Scan

 


C. ROWCOUNT

 

ROWCOUNT stops processing after the specified number of rows. In this example, note that x rows meet the criteria of advances less than or equal to $5,000; however, from the number of rows returned by the update, you can see that not all rows were processed. ROWCOUNT affects all Transact-SQL statements.

 

SELECT Count = count(*)
 FROM titles
  WHERE advance >= 5000
go

 


Count      
-----------
10          

 

(1 row(s) affected)

 

SET ROWCOUNT 4
go
UPDATE titles
 SET advance = 5000
  WHERE advance >= 5000
go
(4 row(s) affected)

 


D. ANSI NULL Default, Create Tables and sp_help

 

The publishers table is created without explicitly defining the nullability for each of the columns. In the INSTPUBS.SQL script, all nullability is explicitly defined. But for this example, all NULL definitions were replaced by a single SET option defined prior to the CREATE TABLE batch. Also note that the SET option is explicitly turned off within the script.
In scripts run against databases where nullability may be changed, make sure to do one of the following:

 

· Explicitly define the nullability for each column.
· Manually set the nullability for the script's session using one of the ANSI NULL default options.

 

SET ANSI_NULL_DFLT_ON ON
go
CREATE TABLE publishers
(
 pub_id char(4) NOT NULL
  CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
  CHECK (pub_id in ('1389', '0736', '0877', '1622', '1756')
   OR pub_id like '99[0-9][0-9]'),
 pub_name  varchar(40),
 city   varchar(20),
 state  char(2),
 country  varchar(30)   DEFAULT('USA')
)
go
sp_help publishers
go

 

/* For simplicity only a subset of the results of sp_help is
 shown here. */

 

Column_name Nullable
------------- --------------
pub_id no
pub_name yes
city yes
state yes
country yes

 

SET ANSI_NULL_DFLT_ON OFF

 


E. TRANSACTION ISOLATION LEVEL in an Explicit Transaction

 

In this example, the TRANSACTION ISOLATION LEVEL is set for the session. For each Transact-SQL statement that follows, SQL Server will hold all of the shared locks until the end of the transaction.

 

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
go
BEGIN TRANSACTION
SELECT * FROM publishers
SELECT * FROM authors
...
COMMIT TRANSACTION

 


F. Arithmetic Handling

 

In this example, all arithmetic SET options and the results displayed by an invalid entry are shown. Table t1 is created with only one column of type tinyint
. In the statements that follow, the default SQL Server behavior, and ARITHABORT and ARITHIGNORE are shown.

 

CREATE TABLE t1
(
 col1  tinyint  NOT NULL
)
go
INSERT t1 VALUES(-1)
go
Arithmetic overflow occurred.
(0 row(s) affected)
SET ARITHABORT ON
go
INSERT t1 VALUES(-1)
go
Arithmetic overflow error for type tinyint, value = -1.
SET ARITHABORT OFF
SET ARITHIGNORE ON
go
INSERT t1 VALUES(-1)
go
(0 row(s) affected)


Message édité par Fred999 le 29-03-2010 à 16:10:45
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Gestion de la mémoire (résolu, merci !)

 

Sujets relatifs
stockage de tableau de structure en mémoire partagéeComment allouer de la mémoire pour un tableau (malloc)
[RESOLU] Erreur à la compilation :([pascal] programme pascal qui transforme "123" en "102030" résolu
gestion d'intérruptions, modification 80x86[Résolu] Bloquer l'envoi d'un formulaire
[RESOLU] API Console -> Colorer du texte[Résolu] Rester invisible de google pendant qq temps ?
[résolu] calculs avant la compilation, avec le pré-processeurFonction globale: symbole externe non résolu
Plus de sujets relatifs à : Gestion de la mémoire (résolu, merci !)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR