J'ai un site Web ASP.NET qui fait sa propre mise en cache indépendante des données et les données ne changent pas pendant de longues périodes, il n'a donc pas besoin d'interroger SQL Server une deuxième fois avec la même requête. J'ai besoin d'améliorer les performances des premières requêtes (vierges) qui vont à ce serveur SQL. Certaines requêtes traitent tellement de données qu'elles peuvent entraîner l'utilisation de SQL Server tempdb
. Je n'utilise pas de variables de table temporaire ou de tables temporaires, donc SQL Server décide de l'utiliser tempdb
seul quand il en a besoin.
Ma taille de base de données est de 16 Go, j'ai 32 Go de RAM physique disponible sur ma machine serveur.
Je comprends que la stratégie de mise en cache de MS SQL Server essaie de conserver les données dans la RAM pour accélérer les performances de requêtes similaires si elles ont besoin de charger les mêmes données à nouveau. De plus, il essaiera d'utiliser la RAM disponible au lieu de tempdb pour accélérer les performances sans provoquer d'accès au disque.
Je suppose que lorsqu'une requête qui doit stocker quelque chose dans tempdb SQL Server arrive et qu'il n'y a pas assez de RAM disponible, SQL Server a 2 choix:
1) pour décharger certaines données mises en cache et utiliser de la RAM épargnée au lieu de tempdb pour éviter les écritures sur disque
2) conserver les données en cache pour les requêtes futures et commencer à utiliser tempdb, ce qui ralentit les écritures sur le disque.
Je ne sais pas quel choix SQL Server fera dans cette situation, mais je voudrais qu'il fasse le choix n ° 1 car je ne me soucie que des performances des premières requêtes (vierges), car je n'envoie plus jamais la même requête à SQL Server (même si je peux envoyer une requête similaire).
Quelle est la stratégie de mise en cache SQL Server pour ce scénario?
Comment équilibre-t-il l'utilisation de la RAM entre l'évitement de tempdb pour les requêtes vierges et la vitesse des secondes requêtes?
Est-il possible de configurer SQL Server de telle manière qu'il fera le choix n ° 1? Si oui, alors comment?
Sinon, comment puis-je augmenter les performances de toutes les requêtes SQL vierges?
Étant donné que je ne connais pas la stratégie de mise en cache de SQL Server, je souhaite placer la base de données sur le disque RAM. Cela garantira que toute requête vierge a une vitesse de chargement élevée des données non mises en cache même si SQL Server fait toujours le choix n ° 1. Le risque est que SQL Server puisse commencer à utiliser plus de tempdb avec moins de RAM disponible (il ne reste que 16 Go après avoir utilisé 16 Go pour le disque RAM) s'il continue de faire le choix # 2, ce qui ralentira les requêtes vierges qui provoquent des déversements tempdb
.
Je suis intéressé par la solution pour SQL 2008 R2, mais je suppose que c'est probablement la même chose pour SQL 2008, SQL 2005 et peut-être SQL 2000.
Clarifications:
Il n'y a aucune autre application en cours d'exécution sur cette boîte, elle est dédiée à SQL Server . Le site Web fonctionne sur une boîte séparée.
Il s'agit de SQL Server 2008 R2 Standard Edition 64 bits sur Windows Server 2008 R2 Enterprise 64 bits.
J'exécute uniquement les requêtes en lecture seule et la base de données est définie en lecture seule .
Supposons qu'il existe déjà de bons index . Cette question concerne SQL Server faisant le choix n ° 1 par rapport au choix n ° 2, comment le fait-il, s'il existe un moyen de le contrôler et si le disque RAM l'aide à faire le bon choix pour les requêtes vierges.
Réponses:
Votre question peut être reformulée comme suit: «Comment fonctionne la subvention de mémoire de requête?». Une bonne lecture sur le sujet est Comprendre l'attribution de mémoire au serveur SQL . Avant qu'une requête soit lancée en exécution, elle peut nécessiter une allocation de mémoire pour les tris et les hachages et d'autres opérations gourmandes en mémoire. Cette allocation mémoire est une estimation . En fonction de l'état actuel du système (nombre de demandes en cours et en attente, mémoire disponible, etc.), le système accorde à la requête une allocation de mémoire jusqu'à la quantité requise. Une fois la mémoire accordée, la requête démarre son exécution (il peut être nécessaire d'attendre dans la file d'attente redoutée du «sémaphore de ressource» avant d'obtenir l'octroi). À l'exécution, l'allocation de mémoire est garantiepar le système. Cette quantité de mémoire peut être partagée avec des pages de données (car elles peuvent toujours vider le disque) mais jamais avec une autre utilisation de la mémoire (c'est-à-dire qu'elle ne peut pas être soumise à «voler»). Ainsi, lorsque la requête commence à demander de la mémoire validée à son octroi, le moteur déploiera ce que vous appelez la `` stratégie # 1 '': les pages de données peuvent être supprimées (vidées si elles sont sales) afin de donner à la requête la mémoire qui lui a été promise. Maintenant, si l'estimation était correcte et que la subvention représentait 100% de la mémoire demandée, la requête ne devrait pas «déborder». Mais si l'estimation était incorrecte (se résume à des estimations de cardinalité, elle est donc soumise à des statistiques obsolètes) ou si la requête n'a pas obtenu l'intégralité de la subvention qu'elle avait demandée, la requête «débordera». C'est à ce moment que tempdb entre en scène et que les performances sont généralement des tanks.
Le seul bouton dont vous disposez pour contrôler quelque chose dans ce processus est le gouverneur de ressources . Étant donné que le RG peut être utilisé pour spécifier un paramètre MIN pour un pool, il peut être utilisé pour réserver de la mémoire pour une certaine charge de travail afin qu'il obtienne réellement l'allocation de mémoire qu'il demande. Bien sûr, après avoir fait l'enquête appropriée qui montre que les allocations de mémoire réduites sont le coupable, et bien sûr après que l'impact sur les autres charges de travail a été évalué. Et testé, bien sûr.
Revenons maintenant à votre question d'origine. Si votre enquête est correcte (un très gros si), je voudrais signaler deux problèmes:
Donc, cela me dit que vous avez un problème fondamental de conception et d'architecture. Les sites Web sont guidés par la latence et doivent créer une charge de travail de type OLTP, sans octroi de mémoire et sans pression de mémoire sur les requêtes. Sans parler des déversements. Les requêtes analytiques doivent être exécutées dans des travaux hors ligne et stocker les résultats prétraités pour une disponibilité rapide lorsque les requêtes HTTP le souhaitent.
la source
sys.dm_exec_query_memory_grants
: vous avezrequested
(le max),required
(le min) etgranted
(le réel).Ce que vous n'avez pas mentionné, c'est quel type de requêtes sont exécutées sur la base de données et s'il existe de bons index pour accélérer les performances de vos requêtes.
Vous devez également vous assurer qu'il existe d'autres applications en cours d'exécution sur la même boîte. Même si la boîte a 32 Go de RAM, avez-vous défini un paramètre de mémoire maximale sur le serveur de base de données pour mettre une limite artificielle. S'il existe des applications exécutées sur le même serveur, SQL et les autres applications peuvent être en concurrence pour les ressources et notez que SQL est très gourmand en mémoire.
SQL Server utilisera tempdb pour le tri interne ou les jointures / agrégats de hachage ou les opérateurs de spoule, etc. et vous ne pouvez pas contrôler ce comportement. Ce que vous pouvez faire, c'est limiter la quantité de données renvoyées.
Avez-vous vérifié les statistiques d'attente sur cette case? Chaque fois que SQL Server attend une ressource, SQL Server suit la ressource d'attente et la consultation de ces informations est utile.
Regardez les requêtes de diagnostic de Glenn Berry et ce sera un bon début pour vous.
Regardez également PARAMETERIZATION FORCED comme mentionné dans http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspx
la source
Cette question se lit actuellement comme une solution à la recherche d'un problème. Vous avez décidé qu'un disque RAM est la solution et vous voulez que quelqu'un valide ce choix. Désolé, ça n'arrivera pas.
Si vous avez mesuré et observé un déversement sur tempdb, cela sera presque certainement dû à une opération de tri ou de hachage et à une allocation de mémoire de requête insuffisante. Selon le volume de données à traiter, cela peut être inévitable, mais de bonnes chances que la requête et / ou l'indexation puissent être améliorées pour l'éviter.
Jetez un œil à Buffer Management pour mieux comprendre comment SQL Server gère la mémoire et SQL Server Memory Management Expliqué pour certains outils de base et requêtes DMV pour comprendre où votre mémoire est allouée.
C'est un gros sujet. Publiez la requête et le plan et vous obtiendrez des commentaires ciblés.
la source