2009-11-05 7 views
1

asp.net et le serveur sql, ont sqls pour sélectionner un sous-ensemble de lignes, je dois le comte * souventPerformance du comte sql *

Bien sûr, je peux avoir un select count (*) pour chacun de ces sqls dans chaque aller-retour mais bientôt il deviendra trop lent.

-Que faites-vous vraiment vite?

Répondre

1

Vous rencontrez un problème qui ne peut pas être résolu en ajoutant un autre index à votre table? COUNT (*) opérations sont généralement O (log n) en termes de lignes totales, et O (n) en termes de lignes retournées.

Edit: Ce que je veux dire est (au cas où je mal compris votre question)

Compte tenu de cette structure:

CREATE TABLE emails (
    id INT, 
    .... OTHER FIELDS 
) 

CREATE TABLE filters (
    filter_id int, 
    filter_expression nvarchar(max) -- Or whatever... 
) 

Créer la table

CREATE TABLE email_filter_matches (
    filter int, 
    email int, 
    CONSTRAINT pk_email_filter_matches PRIMARY KEY(filter, email) 
) 

Les données contenues dans ce tableau devraient être mis à jour chaque fois qu'un filtre est mis à jour, ou lorsqu'un nouvel email est reçu.

Ensuite, une requête comme

SELECT COUNT(*) FROM email_filter_matches WHERE filter = @filter_id 

doit être O (log n) en ce qui concerne le nombre total de correspondances de filtre, et O (n) en ce qui concerne nombre de résultats correspondant à ce filtre particulier. Puisque votre exemple montre seulement un petit nombre de correspondances (ce qui semble réaliste quand il s'agit de filtres d'email), cela pourrait très bien être OK. Si vous le souhaitez, vous pouvez bien sûr créer un déclencheur sur la table email_filter_matches pour conserver une valeur mise en cache dans la table des filtres, mais cela peut être fait le jour où vous rencontrez des problèmes de performances. Ce n'est pas trivial d'avoir ce genre de choses dans les systèmes concurrents.

+0

Comme je l'ai mentionné, les filtres sont définis par les utilisateurs, donc les clauses sont imprévisibles et peuvent être complexes et longues pour le serveur. Il existe également des champs personnalisés qui rendent les clauses where plus imprévisibles. Et si vous faites quelques décomptes * où ... dans chaque aller-retour contre un grand nombre de lignes cela causera des problèmes de performance indépendamment des index, etc Index ferait si la requête était prévisible ou au moins simple –

0

Voici quelques idées pour accélérer COUNT (*) au niveau des données:

  1. Gardez la table et l'index cluster aussi étroite que possible, de sorte que plusieurs lignes correspondent par page
  2. Conserver les critères de filtrage aussi simple que possible, de sorte que le comptage va vite
  3. Faites ce que vous pouvez pour vous assurer que les lignes à compter sont en mémoire avant de commencer à les compter (peut-être en utilisant la pré-mise en cache)
  4. Assurez-vous que votre le matériel est optimisé (assez de RAM, disques assez rapides, etc.)
  5. Tenir compte des résultats de la mise en cache dans des tableaux distincts

Comme alternative, si seuls les filtres changent fréquemment et non les données elles-mêmes, vous pourriez envisager la construction d'un cube à l'aide Analysis Services, et exécutez vos requêtes contre cela.