2009-10-07 9 views
2

J'ai une requête qui renvoie 10000 d'enregistrements qui sont utilisés comme points de tracé sur une carte. Dans un effort pour réduire la charge, et augmenter la vitesse de l'application, nous essayons de mettre en œuvre ce qui revient essentiellement à la logique Level of Detail. Fondamentalement, en zoom arrière, afficher 50% des points. Lorsque vous effectuez un zoom avant, affichez 100% des points.Renvoyer tous les autres enregistrements avec LINQ

C'est en fin de compte ce que je dois le SQL final à ressembler à:

SELECT * 
FROM 
    (SELECT 
     [t0].[RecordName], 
     [t0].[LastMaintenanceDate] 
     ,Row_Number() OVER (ORDER BY [t0].Ticker) as RowNumber 
     FROM 
      [dbo].[TableName] AS [t0] 
    )as [t1] 
WHERE RowNumber % 2 = 0 

En LINQ je peux utiliser .Skip et .Take pour obtenir le ROW_NUMBER() sur une partie (example here), mais quand vous le faites , le critère Where génère utilise 'between' au lieu de 'where RowNumber% 2 = 0' dont j'ai besoin.

Est-ce que je m'approche de cela correctement? Afin d'obtenir les gains de performances complets que nous recherchons ici, cette exclusion doit vraiment se produire sur le serveur SQL.

+0

Ceci est un problème très intéressant, et malheureusement je ne connais pas la réponse en utilisant LINQ to SQL pur. La seule chose que je peux suggérer est que LINQ to SQL * supporte * ad-hoc [requêtes SQL brutes] (http://msdn.microsoft.com/en-us/library/bb399403.aspx). Votre problème peut être un cas valide pour ce faire. – Randolpho

Répondre

2

Quelles colonnes avez-vous dans votre tableau? Si vous avez par exemple une colonne de clé primaire identité int, vous pouvez l'utiliser ...

from mt in dc.MyTable 
where mt.ID %2 == 0 
select mt 

... ou ...

where mt.SomeDataTime.Millisecond % 2 == 0 

... Cela dit, où êtes-vous essayant de réduire la charge? Le T-SQL dans votre message, ainsi que les deux solutions que j'ai mentionnées forceront toutes les analyses de table complètes, donc si votre table est grande, il vaut mieux que vous puissiez réduire les enregistrements basés sur quelque chose indexé (et où le prédicat where clause peut réellement utiliser l'index) ...

+0

J'ai une colonne de type ID sur laquelle je peux utiliser cette logique, donc le "where mt.Ticker% 2 == 0" a parfaitement fonctionné pour ce que j'essaie de faire. J'ai apparemment besoin d'en savoir plus sur l'opérateur% et comment cela fonctionne. Je ne l'ai jamais utilisé avant hier quand je l'ai trouvé dans l'exemple de lien que j'ai posté. Merci encore!! –

+0

btw, le commentaire sur l'analyse de la table complète est également utile. Heureusement dans ce cas, l'indexation de la colonne en question ne devrait pas être un problème. –

+0

C'est une bonne idée, à condition que les résultats ne soient pas filtrés avant de prendre toutes les autres lignes. Ajoutez n'importe quel type de filtre sur ceci, et la distribution changera. Vous pouvez ne pas sauter les lignes de manière égale et il est peu probable (en fonction de la distribution finale créée par le filtre) que vous réduisiez votre volume de ligne de moitié. Je vous préviens juste. Si vous souhaitez filtrer les résultats avant d'ignorer toutes les autres lignes, vous devez utiliser une procédure stockée. – Randolpho

0

Le projet morelinq dispose d'une fonction TakeEvery qui le fait, mais cela ne fonctionne que sur IEnumerable.

Il devrait être possible de créer une méthode d'extension pour résoudre ce problème (mon environnement de développement n'est pas disponible pour le moment, donc je ne peux pas le tester pour le moment).

Dans votre exemple spécifique, je suppose qu'une méthode d'extension à Table suffirait.

Si vous souhaitez essayer ceci, il existe un 'exemple' de création d'une méthode d'extension à une table here.

Questions connexes