Question

Je vais avoir un problème de performance très particulier au travail!

Dans le système que nous utilisons, il y a une table qui contient des informations sur le processus de flux de travail actuel. L'un des champs détient une feuille de calcul qui contient des métadonnées sur le processus (ne me demandez pas pourquoi !! et NON JE NE CHANGERA PAS le !!)

Le problème est que cette feuille de calcul est stocké dans un champ d'image dans un SQL Server 2005 (dans une base de données SQL compatibilité ensemble avec 2000).

Ce tableau a actuellement 22K + lignes et même une simple requête comme ceci:

SELECT TOP 100 *
  FROM OFFENDING_TABLE

Prend 30 secondes pour récupérer les données dans Query Analyzer.

Je pense à la mise à jour de la compatibilité avec SQL 2005 (une fois que j'ai été informé que l'application peut gérer).

La deuxième chose que je pense est de changer le type de données de la colonne à varbinary(max) mais je ne sais pas si cela cela affectera l'application.

Une autre chose que je considère est d'utiliser sp_tableoption pour définir le large value types out of row à 1 comme il est actuellement 0, mais je n'ai aucune information si ce faisant améliore les performances.

Quelqu'un sait comment améliorer les performances dans un tel scénario?


Sous la direction de clarifier

Mon problème est que je n'ai aucun contrôle sur ce que l'application demande au serveur SQL, et je l'ai une réflexion sur elle (l'application est un site Web .NET 1.1) et il utilise le champ incriminé pour des choses internes que je ont aucune idée de ce qu'il est.

Je dois améliorer la performance globale de ce tableau.

Était-ce utile?

La solution

Je vous recommande de regarder dans la mise en page de la table incriminée santé:

select * from sys.dm_db_index_physical_stats(
       db_id(), object_id('offending_table'), null, null, detailed);

Les choses semblent trop pour avg_fragmentation_in_percent sont, page_count, avg_page_space_used_in_percent, Record_Count et ghost_record_count. Cues comme une fragmentation élevée ou un nombre élevé d'enregistrements fantômes, ou un pour cent utilisé à faible page indiquent les problèmes et les choses peuvent être améliorées tout à fait un peu juste en reconstruction de l'index (la table.) À partir de zéro:

ALTER INDEX ALL ON offending_table REBUILD;

Je dis cela étant donné que vous ne pouvez pas changer la table, ni l'application. Si vous seriez en mesure de changer la table et l'application, les conseils que vous avez déjà obtenu de bons conseils (ne pas utiliser « * », économisons sélectionnez w / condition oa, utilisez le nouveau type varbinary (max) etc etc) .

Je voudrais aussi regarder dans la durée de vie moyenne de la page dans les compteurs de performance pour comprendre si le système est une mémoire affamée. D'après votre description des symptomps le système recherche IO lié qui me conduit à penser qu'il ya peu de mise en cache de la page en cours, et plus de RAM pourrait aider, ainsi qu'un IO plus rapide sous-système. Sur un système SQL 2008 Je suggère également tourner la compression de page, mais sur 2005 vous ne pouvez pas.
Et, juste pour être sûr, assurez-vous que les requêtes ne sont pas bloquées par affirmation de l'application elle-même, à savoir. la requête ne passe pas 90% de ces 30 secondes d'attente pour un verrou. Regardez sys.dm_exec_requests pendant que la requête est en cours d'exécution, consultez le wait_time , wait_type et wait_resource. Est-il PAGEIOLATCH_XX? Ou est-ce une serrure? En outre, comment est sys.dm_os_wait_stats sur votre serveur, ce sont les raisons d'attente? top

Autres conseils

D'abord - ne jamais pas faire SELECT * dans le code de production - rapports ou non.

Vous avez trois choix fondamentaux:

  • déplacer ce champ blob dehors dans une table séparée si elle est pas toujours nécessaire; probablement pas pratique puisque vous mentionnez que vous ne pouvez pas modifier le schéma

  • être plus prudent avec vos relevés de SELECT pour sélectionner uniquement les champs que vous avez vraiment besoin - et omettez le champ blob

  • voir si vous pouvez limiter votre requête pour inclure une clause de WHERE et de trouver un moyen d'optimiser le plan de requête par exemple l'ajout d'un indice approprié à la table (si vous pouvez)

Il n'y a pas de magie « faire de ce plus rapide » switch - mais vous pouvez optimiser votre requête ou d'optimiser votre mise en page de table. Les deux aide. Si vous ne pouvez pas changer quoi que ce soit - ni la mise en page de table, ni ajouter un index, ni modifier les requêtes, vous aurez du mal à optimiser quoi que ce soit, j'ai peur ....

Il suffit de changer le champ VARBINARY (MAX) ne changera rien du tout -. Aucune amélioration de la performance à attendre que de changer le type de données

Une réponse courte est seulement faire défavorise plusieurs lignes lorsque les champs retournés ne comprennent pas le champ de l'image incriminée, c.-à-pas SELECT *. Si vous voulez que la valeur du champ d'image, récupérer au cas par cas.

Réglage des grands types de valeur de l'option de la ligne devrait certainement aider à la performance. La taille de ligne sera nettement plus faible, SQL Server peut faire beaucoup moins lectures physiques pour obtenir throught le tableau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top