2010-04-08 7 views
1

Nous avons repris un site Web d'une autre société après qu'un client a décidé de changer.Lignes SQL Server 15MM, requête COUNT simple. 15+ secondes?

Nous avons une table qui se développe d'environ 25k enregistrements par jour, et est actuellement à 15MM enregistrements.

Le tableau ressemble à quelque chose comme:

id (PK, int, not null) 
member_id (int, not null) 
another_id (int, not null) 
date (datetime, not null) 

SELECT COUNT(id) FROM tbl peut prendre jusqu'à 15 secondes.

Une jointure interne simple sur 'another_id' prend plus de 30 secondes.

Je ne peux pas m'imaginer pourquoi cela prend tant de temps. Aucun conseil?

SQL Server 2005 Express

+0

Qu'est-ce que 15MM? 15 milliards? – jball

+1

La table est-elle indexée? (Peut-être que l'indice PK a été supprimé pour accélérer les insertions quotidiennes de 25k?) – dmb

+0

15 millions. le PK est là de ce que je peux voir. – john

Répondre

1

Notez que la COUNT(id) entraîne généralement une analyse complète de la table, il doit lire toute la table pour obtenir le nombre. Si le comptage est vraiment une chose très importante pour vous, vous pouvez envisager de créer un déclencheur pour stocker les résultats du compte dans une autre table.

Sans la requête, je ne peux pas dire grand-chose sur le inner join, mais je pense serait que vous ne disposez pas d'un index de chaque id ou another_id

+0

ou la sélectivité de another_id est très mauvaise –

+0

vous aviez raison. ils n'étaient pas indexés. – john

+0

en fonction de l'autre travail dans la transaction lors de l'insertion des 25k lignes (sont-ils des utilisateurs travaillant ou en vrac?), Cette mise à jour de la même ligne à chaque fois ralentira votre système avec blocage et blocage. –

3

Si vous avez besoin d'un nombre de lignes, mais vous pouvez vivre d'une valeur approximative (pas 100% garanti pour être exact - mais vous donne un ordre de grandeur), vous pouvez utiliser les vues du catalogue système SQL Server pour y parvenir comme ceci:

SELECT 
    t.Name AS TableName, 
    sum(p.rows) as RowCounts 
FROM 
    sys.tables t 
INNER JOIN  
    sys.indexes i ON t.OBJECT_ID = i.object_id 
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id 
WHERE 
    t.Name = 'Your Table Name' 
    i.OBJECT_ID > 255 AND 
    i.index_id <= 1 
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name 

Étant donné une table dans votre base de données, cela vous donnera une approximation du nombre de lignes dans cette table, et c'est très très rapide (pas m esurables - moins de 0,01 sec)

+0

count (*) n'est pas le seul problème, OP dit 'Une simple jointure interne sur 'another_id' prend plus de 30 secondes. –

+1

@KM: oui, je sais - j'offrais juste une solution pour un des problèmes mentionnés - l'autre a été adressée par indexation, je crois –

+0

+1 Si vous avez simplement besoin d'un nombre approximatif de toutes les lignes que c'est une très bonne solution. – Wolph

0

15 million lignes en cours d'exécution sur SQL Server 2005 Express

quel type de matériel utilisez-vous.? votre base de données peut être configurée correctement, mais si vous n'êtes pas sur un bon serveur dédié avec beaucoup de RAM, les requêtes sur une grande table comme celle-ci seront lentes.

+0

Grande table? Pas tellement imho ... je veux dire, 4 colonnes, 3 ints qui signifieraient soit des numéros 32bit ou 64bit et un datetime, aussi 32bit ou 64bit. Donc ... c'est '32 * 4 * 15 000 000 bits = 229 mégaoctets 'de mémoire ou double de cela dans le cas d'entiers 64 bits/datetimes. Même un simple ordinateur de bureau pourrait facilement gérer cela, d'autant plus que pour un 'COUNT (id)' vous n'avez besoin que d'un quart de cela en mémoire. – Wolph

+0

(4 + 4 + 4 + 8) octets * 15000000 lignes = 286 mégaoctets et ce sont les données seulement aucun autre frais généraux, pour ne pas mentionner les index ou d'autres tables. En ajoutant juste un index à cette table sur un de ces ints (pour un fk probablement) ajoutera encore 57+ mégaoctets dans les données seules 4 * 15m, et deux fois plus si c'est le datetime, et Sql Server Express est limité à 1 gig de ram: microsoft.com/Sqlserver/2005/en/us/ ... si ce n'est pas sur un serveur, les E/S seront plus lentes, et si d'autres applications sont en cours d'exécution (IIS, échange, etc), les choses tourneront plus lentement –