J'ai une Employee
table qui contient un million d'enregistrements. J'ai suivi SQL pour paginer des données dans une application Web. Cela fonctionne bien. Cependant, ce que je vois comme un problème est - la table dérivée tblEmployee
sélectionne tous les enregistrements de la Employee
table (pour créer les MyRowNumber
valeurs).
Je pense que cela entraîne la sélection de tous les enregistrements de la Employee
table.
Est-ce que ça marche vraiment? Ou SQL Server est-il optimisé pour sélectionner uniquement les 5 enregistrements de la Employee
table d' origine ?
DECLARE @Index INT;
DECLARE @PageSize INT;
SET @Index = 3;
SET @PageSize = 5;
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as MyRowNumber,*
FROM Employee) tblEmployee
WHERE MyRowNumber BETWEEN ( ((@Index - 1) * @PageSize )+ 1) AND @Index*@PageSize
Réponses:
Une alternative au test pourrait être:
Oui, vous avez frappé la table deux fois, mais dans le CTE où vous scannez la table entière, vous ne saisissez que la clé, pas TOUTES les données. Mais vous devriez vraiment regarder cet article:
http://www.sqlservercentral.com/articles/T-SQL/66030/
Et la discussion de suivi:
http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx
Dans SQL Server 2012, vous pouvez bien sûr utiliser la nouvelle syntaxe
OFFSET
/FETCH NEXT
:la source
Bien que vous ne connaissiez peut-être pas le mécanisme sous-jacent, vous pouvez le tester vous-même en comparant les performances de votre requête à: sélectionnez * dans Employé.
Les versions les plus récentes de SQL Server optimisent assez bien, mais cela peut dépendre de plusieurs facteurs.
Le fonctionnement de votre fonction ROW_NUMBER sera déterminé par la clause Order By. Dans votre exemple, la plupart penseraient que EmpID est la clé primaire.
Il y a des clauses where qui sont si complexes et / ou mal codées ou indexées, il est préférable de simplement renvoyer l'ensemble de données (c'est rare et peut être corrigé). L'utilisation de BETWEEN présente des problèmes.
Avant de supposer qu'il serait préférable de renvoyer toutes les lignes à votre application et de la laisser le comprendre, vous devez travailler sur l'optimisation de votre requête. Vérifiez les estimations. Demandez à l'analyseur de requêtes. Testez quelques alternatives.
la source
Je sais que la question concerne row_number () mais je veux ajouter une nouvelle fonctionnalité de sql server 2012. Dans sql server 2012, la nouvelle fonctionnalité OFFSET Fetch a été introduite et elle est très rapide que row_number (). Je l'ai utilisé et cela me donne de bons résultats j'espère que vous remplissez également la même expérience.
J'ai trouvé un exemple sur http://blogfornet.com/2013/06/sql-server-2012-offset-use/
ce qui est utile. J'espère que cela vous aidera aussi à mettre en œuvre de nouvelles fonctionnalités ....
la source
Je ne pense pas qu'il évalue pour retourner toutes les lignes de la table d'origine. Le serveur SQL est optimisé. Sinon, il faudra énormément de temps pour sélectionner un million d'entrées. J'utilise actuellement cela et c'est beaucoup plus rapide que de sélectionner toutes les lignes. Donc, bien sûr, n'obtient pas toutes les lignes. Il est cependant plus lent que de simplement récupérer les cinq premières lignes, probablement en raison du temps nécessaire à la commande.
la source
la source