8
votes

Problème de performance ASP.NET/SQL 2008

Nous avons développé un système avec un écran de recherche qui ressemble un petit quelque chose comme ceci:


(source: Nsourceservices.com )

Comme vous pouvez le constater, il existe des fonctionnalités de recherche assez graves. Vous pouvez utiliser n'importe quelle combinaison de statuts, de canaux, de langues, de types de campagnes, puis de le réduire ensuite par nom et ainsi de suite.

Puis, une fois que vous avez fouillé et que les câbles apparaissent en bas, vous pouvez trier les en-têtes.

La requête utilise Rownum pour faire un schéma de radiomessagerie, nous ne renvoyons donc quelque chose comme 70 lignes à la fois.

le problème

Même si nous ne retournons que 70 lignes, beaucoup d'IO et de triont. Cela donne un sens bien sûr.

Cela a toujours causé des pointes mineures à la file d'attente de disque. Cela a commencé à ralentir plus lorsque nous atteignons 3 millions de prospects, et maintenant que nous nous rapprochons de 5, la file d'attente de disque piquets jusqu'à une seconde ou deux droite parfois.

Ce serait toujours difficile, mais ce système a une autre zone avec un processus sensible au temps, disons pour la simplicité qu'il s'agit d'un service Web, qui doit servir des réponses très rapidement ou cela entraînera un délai d'attente de l'autre. finir. Les pointes de la file d'attente de disque provoquent cette partie de la tourbière, ce qui provoque des délits en aval. Le résultat final est en fait abandonné les appels téléphoniques dans notre IVR automatisé basé sur voixXML, et c'est très mauvais pour nous.

ce que nous avons essayé

Nous avons essayé:

  • Tâches de maintenance qui réduisent le nombre de prospects dans le système au strict minimum.
  • a ajouté les indices évidents pour aider.
  • a dirigé l'assistant de syntonisation d'index dans le profileur et appliqué la plupart de ses suggestions. L'un d'entre eux allait se reproduire plus ou moins de reproduire toute la table dans un index alors je l'ai modifié à la main pour faire un peu moins que cela.
  • a ajouté plus de RAM sur le serveur. C'était un peu bas mais maintenant, il a toujours quelque chose comme 8 gigs inactif, et le serveur SQL est configuré pour ne pas utiliser plus de 8 concerts, mais elle n'utilise jamais plus de 2 ou 3. J'ai trouvé cela impair. Pourquoi ne pas simplement mettre la table entière dans la RAM? Ce n'est que 5 millions de prospects et il y a beaucoup de place.
  • a versé des plans d'exécution de requête. Je peux voir qu'à ce stade, les index semblent principalement faire leur travail - environ 90% des travaux se produisent pendant la phase de tri.
  • considérés comme partitionnement de la table des prospects à un lecteur physique différent, mais nous n'avons pas les ressources pour cela, et cela semble que cela ne devrait pas être nécessaire.

    en fermeture ...

    Une partie de moi semble que le serveur devrait pouvoir gérer cela. Cinq millions d'enregistrements ne sont pas essentiellement étant donné la puissance de ce serveur, qui est un noyau quadrial décent avec 16 concerts de RAM. Cependant, je peux voir comment la partie de tri provoque des millions de lignes à toucher juste pour renvoyer une poignée.

    Alors qu'as-tu fait dans des situations comme ça? Mon instinct est que nous devrions peut-être réduire certaines fonctionnalités, mais s'il y a un moyen de garder cette intacte qui me sauvera une guerre avec l'unité commerciale.

    Merci d'avance!


15 commentaires

Recherchez-vous des GUDS? Quel est votre index en cluster? Avez-vous envisagé un SSD sur le serveur? Faites-vous des recherches génériques? Si tel est le cas, vous devrez peut-être indexer les Varchars à l'envers et en avant


@Matthew PK: Aucun GUD. L'index en cluster est juste la clé principale - leadInd (int). Quant à un lecteur d'état solide ... Eh bien, jetant de l'argent à ce sujet doit être ma dernière option de fossé. Mais c'est dans mon esprit. :)


Qu'en est-il de renvoyer l'ensemble du jeu de résultats et de la pagination sur le client? En tant qu'utilisateur, je préférerais attendre une supplément de 2 secondes à l'avance que d'attendre chaque fois que je suis une page.


La requête est-elle intégrée à Dynamic SQL ou est-ce une requête fixe? Pourrait être la requête elle-même doit être accordée non plus aux index.


@Matthew pk: hmm je n'avais pas vraiment considéré cela. Le problème est que l'ensemble des résultats pourrait comporter jusqu'à des millions de prospects et dans ASP.NET, je pense que cela devrait aller directement dans la vision, à moins que je ne changeais de directions entièrement et que je l'ai fait en fait sur le client Avec une sorte de jQuery, ou peut-être avec quelque chose comme Silverlight. Il ne semble pas que cela fonctionnerait, mais d'être honnête, je n'ai pas encore ramifié dans ce type de développement. Pensez-vous que c'est une option légitime avec des millions de prospects sur le fil?


@Hlgem: Eh bien, il est construit par un orj. C'est donc une grosse requête paramétrée. Vous pourriez avoir raison à ce sujet, peut-être que je devrais obtenir le SQL qu'il émet et le poster.


@HLGEM: Cela peut également être dans le domaine où une orèse n'est tout simplement pas la meilleure option. Actully je perd probablement une tonne d'IO au nombre de champs qu'elle tire.


ORM peut être dangereux si vous supposez qu'il optimise votre requête. Pour une requête de performance, vous pourriez envisager d'utiliser un SP (ou même un modèle pour décider d'un SP spécifique en fonction des critères de recherche). Je pense que vous avez raison à propos de l'ASP et du ViewState ... Dumping Un million de lignes Il n'ya peut-être pas la meilleure option.


Cela peut être trop évident ... utilisez-vous la version 64 bits de SQLServer?


@Matthew PK La recherche sur les GUID ne provoquera pas ces sortes de problèmes. J'ai plus de disques que cela, tous les identifiants sont des Guids, et cela fonctionne très bien. De plus, retourner> Les enregistrements et le tri 2 m dans JavaScript sont une mauvaise idée, une mauvaise idée. Vous pouvez également utiliser XML pour votre magasin de données (Blech).


@David, vraie mais la performance de tri peut être affectée par l'index en cluster ... dans ce cas pas vraiment pertinent.


@Matthew pk: Oui, c'est 64 bits. J'ai double vérifié.


@Matthew PK: L'ORM construit effectivement une requête absurde. Je posterais ici mais c'est 8k de texte solide, lol. :) C'est là que je vais maintenant concentrer mes efforts!


@Brian mackay bien dans ce cas je vais l'ajouter comme une réponse: p


Que diriez-vous si vous initiez un autre thread pour lancer l'affichage des premières lignes du jeu de résultats tandis que la requête continue de rechercher les informations souhaitées?


3 Réponses :


2
votes
  1. Déterminez les requêtes ad-hoc seront probablement exécutées ou limiteront les critères de recherche avec les procédures stockées. Pouvez-vous résumer les données? .. Traitez cette < app comme un entrepôt de données.
  2. Créez des index sur chaque colonne impliquée dans la recherche pour éviter les analyses de la table.
  3. Créer des fragments sur les expressions.
  4. réorganise périodiquement les statistiques de données et de mise à jour car plus de prospects sont chargés.
  5. Mettez les fichiers temporaires créés par requêtes (ensembles de résultats) dans RAMDISK.
  6. envisagez de migrer vers un moteur RDBMS hautes performances comme Informix Online.
  7. initier un autre fil pour commencer à afficher N lignes de la définition de résultats tandis que la requête
    continue d'exécuter.

5 commentaires

Bonnes choses ... En outre, alors que vous n'obtenez pas cette erreur, les étapes sont toujours applicables: Stackoverflow.com/questions/4719841/...


Sauf si vous contrôlez soigneusement vos questions (et je suppose que l'orme ne le fais pas non plus) Les indices excessives peuvent provoquer le plan de DB d'essayer un plan «Jack de tous les métiers» plutôt que de sélectionner le "meilleur" index pour un type donné de chercher.


C'est vraiment intéressant, avez-vous un outil spécifique que vous utilisez pour la construction de Ramdisks? Google a trouvé Ramdisk et Ramdisk Plus.


@Brian: Ramdisk Plus 11 .. Vous devez également déterminer combien d'utilisateurs simultanés effectueront des requêtes. La planification des capacités déterminera le nombre de concerts de votre application à votre application.


@BrianMackay: Serait-il possible d'initier un autre thread pour commencer à afficher les résultats de la recherche, même si la requête n'a pas encore terminé la construction du jeu de résultats?



3
votes

Les goulots d'étranglement de la base de données peuvent être fréquemment améliorés en améliorant vos requêtes SQL. Sans savoir ce que celles-ci ressemblent, envisagez de créer un magasin de données opérationnelles ou un entrepôt de données que vous remplissez sur une base planifiée.

Attraper parfois vos bases de données relationnelles complexes est la voie à suivre. Il peut faire fonctionner de manière significative des requêtes, et il est beaucoup plus facile d'optimiser vos requêtes, car le modèle est très plat. Cela peut également faciliter la détermination de déterminer si vous devez augmenter votre serveur de base de données. Une analyse de capacité et de croissance peut aider à faire cet appel.

Les bases de données transactionnelles / hautement normalisées ne sont généralement pas aussi évolutives qu'une SAO ou un entrepôt de données.

EDIT: Votre ormes peut avoir des optimisations également que cela peut soutenir, cela peut valoir la peine d'être examinée, plutôt que de simplement regarder sur la manière d'optimiser les requêtes qu'il envoie à votre base de données. Peut-être contourner votre orje tout à fait pour que les rapports puissent être un moyen d'avoir un contrôle total sur vos requêtes afin de mieux performer.


2 commentaires

Encore un autre endroit où les ormes tombent à plat sur leur visage.


Ouais, une orèse est idéale pour certains scénarios, peut-être pas cela. Peut-être que peut-être fonctionner si la solution doit rester orientée ORM pourrait être un modèle de base de données aplatie, avec une couche d'objet simple pour construire les requêtes avec. Je soupçonne que le chemin de la moindre résistance peut être de simplement regarder les moyens d'optimiser les requêtes existantes de l'or.



2
votes

Considérez comment votre orèse crée les requêtes. Si vous avez une mauvaise performance de recherche, vous pouvez peut-être essayer d'utiliser des procédures stockées pour renvoyer vos résultats et, si nécessaire, plusieurs procédures stockées spécifiquement adaptées auxquelles sont utilisés des critères de recherche.


0 commentaires