J'aimerais demander votre aide.
J'ai une table qui ressemble à ceci: p> Il y a d'autres colonnes aussi, mais maintenant, ce n'est pas important. Une autre chose, la clé est un keypair (identifiant, séquenceid) et ceux-ci sont indexés dans la table. Ce que je voudrais, c'est d'obtenir la dernière ligne pour les identifiants donnés.
Par exemple, si MyID = 1 -> Donne-moi le (1,3), Myid = 2 -> Donne-moi l'enregistrement (2,4) et ainsi de suite.
Dans ma table, il y a 500 identifiants et chaque identifiant dispose de 50 000 ID de séquence de sorte que la taille des enregistrements est de 500 * 50 000 p> ma requête: p> Avez-vous une idée de la façon dont je peux le rendre plus rapide? Peut-être une autre requête qui est meilleure que ce que j'utilise? P> Merci pour des réponses. P> BR. P> P>
6 Réponses :
Vous pouvez essayer avec une join interne comme ci-dessous-
SELECT * FROM ( SELECT myId,sequenceId, ROW_NUMBER() OVER(PARTITION BY myId ORDER BY sequenceId DESC) RN FROM myTable )A WHERE RN = 1
Je l'ai essayé avec "Se rejoindre interne" et l'heure d'exécution était plus lente, c'est pourquoi j'utilise "dans"
Premier, @myids est une variable de table, n'est-ce pas? Comment déclarez-vous cela? Est-ce indexé? Ajoutez une clé primaire sur celle-ci:
SELECT * FROM ( SELECT TOP (9223372036854775807) myId MyId, MAX(sequenceId) SequenceId FROM myTable t GROUP BY myId ORDER BY myId ) T WHERE EXISTS (SELECT TOP 1 'X' X from @MyIds m WHERE m.myId = t.myId)
Le @myids est un type créé dans la procédure de magasin que j'utilise.
J'ai essayé de cette façon mais malheureusement, la performance n'a donc pas été améliorée.
Votre requête est correcte et relativement optimale; Vous n'obtiendrez probablement aucune amélioration en la réécrivez d'une autre manière, autre que de remplacer la variable de table avec une table temporaire indexée.
L'optimisation des performances est généralement des indices. Selon que la colonne si l'index en cluster sur la table est créé sur le ID code> est indexée, l'une des options suivantes doit aider: p>
colonne MyID code>, vous pouvez enregistrer un peu d'espace: p>
create table #list (Id int primary key);
insert into #list (Id)
-- Assuming there are no duplicates, otherwise add DISTINCT
select MyId from @MyIds;
SELECT
t.myId AS 'MyId',
MAX(t.sequenceId) AS 'SequenceId'
FROM myTable t
inner join #list l on l.Id = t.myId
GROUP BY t.myId
-- OPTION (RECOMPILE);
Je ne vois pas comment l'index sans la colonne code> ID code> profiterait à la requête de l'OP, car il ne filtre pas par SéquenceID code>.
Je l'ai essayé avec "Se rejoindre interne" et l'heure d'exécution était plus lente, c'est pourquoi j'utilise "dans"
@Ezlo, "Si l'index en cluster sur la table est créé sur la colonne ID".
@ROGERWOLF, oui même avec le clustered par ID code>, il utiliserait l'index en cluster et non le non-clusterné uniquement avec le
SéquenenceID code>, mais peut-être que je manque quelque chose .
Bien dit. Plus1 de moi! Notez que vous peut i> retourner des rangées en ordre décroissant sans perte de parallélisme; Consultez mon message ci-dessous pour éviter de numériser en arrière pour des cas comme celui-ci.
select id.id as id, seq as maxSequence, data.someData as someData from (select id, max(sequenceId) as seq from #tab group by id) id left join #tab data on id.id = data.id and id.seq = data.sequenceId
Je recommanderais ce qui suit: puis pour les performances que vous souhaitez un index sur MyTable (MyID, SéquenceID Desc) code>. p> p>
L'index ne devrait-il pas être MyTable (MyID, SéquenceID Desc) CODE> Pour obtenir le maximum
SéquenenceId code> dans la première correspondance sur
MyID code>?
@Habo. . . Je pense que c'est un meilleur choix. SQL Server peut être intelligent même avec un indice ascendant.
Comme déjà mentionné - si vous avez un index sur MyID, votre requête devrait em> voler. Un index de colonne et / ou Traitement du mode batch peut accélérer de manière spectaculaire les choses. Si vous pouvez ajouter un filtre à votre index, encore mieux. Les tables optimisées de la mémoire et / ou d'autres objets peuvent également accélérer les choses. Tout ce qui dit, permettez-moi d'introduire un nouveau type d'index - l'index virtuel indexation virtuelle en utilisant dbo.rangeab strong> p> première échauffement rapide. Créons une requête le retour des nombres 1 à 10 en ordre croissant et décroissant. Faisons-le sans index et avec un plan d'exécution parallèle. P> retours: strong> p> regarder ^^^ Pas de tri !!! Ainsi, pour l'ordre décroissant de votre requête ressemble à ceci: P> code>. Vous pouvez exploiter Rangeabe ou Jeff Moden's Fntaly .
-- Sample data
DECLARE @table TABLE (id INT NOT NULL, sequenceId INT NOT NULL)--, INDEX xxx(id,sequenceId))
INSERT @table VALUES(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(2,4)
SELECT r.RN, sequenceId = MAX(t.sequenceId)
FROM
(
SELECT MIN(t.id), MAX(t.id), MIN(t.sequenceId), MAX(t.sequenceId)
FROM @table AS t
) AS mm(Mn,Mx,Mns,Mxs)
CROSS APPLY dbo.rangeAB(mm.Mn,mm.Mx,1,1) AS r
CROSS APPLY dbo.rangeAB(mm.Mns,mm.Mxs,1,1) AS r2
JOIN @table AS t
ON r.RN = t.id AND r2.RN = Mxs
GROUP BY r.RN
OPTION (QUERYTRACEON 8649);
Avez-vous un index sur la table?
Texte de OP: Il existe d'autres colonnes aussi, mais maintenant ce n'est pas important. Une autre chose, la clé est un keypair (identifiant, séquenceid) et ceux-ci sont indexés dans la table.
Vous pourriez essayer d'exister ou de rejoindre au lieu d'entrer. Cependant, avec une requête aussi simple, l'optimiseur choisit probablement le même chemin d'exécution. Vous pouvez également essayer d'utiliser une table temporaire au lieu de la variable de table. Voici quelques articles qui entrent en détail sur les deux sujets: Expliqué .com / 2009/06/16 / in-vs-join-vs-existe et SQLSHACK.COM/WHEN-TURE-TEMPORARY-TABLES-VS-TABLES-VARIES
Comment mesurez-vous le temps?
J'utilise SQL Server Management Studio et vérifie le temps d'exécution à ce sujet.
Veuillez ajouter la définition de votre type de table et
Créer des déclarations code> pour les indices de votre table. Ces détails sont cruciaux en matière d'optimisation des performances.
Pouvez-vous ajouter la définition de @myids? Je voudrais vérifier si vous avez ajouté des index sur celui-ci